下午的男士,
我目前正在使用InnoDB作为数据库引擎来测试Master-Master复制设置.
我们使用这个简单的脚本来测试我们从远程服务器在Linux CLI中运行的脚本.
<?php
while(true) {
try {
$conn = mysql_connect('10.0.10.210', 'test', 'test');
if ($conn) {
mysql_select_db('testdb');
$random = rand(0, 1000);
$res = mysql_query("INSERT INTO test VALUES(0, 'test', $random)");
if ($res) {
echo "\n inserted " . microtime();
} else {
echo "\n not inserted " . microtime();
}
mysql_close($conn);
} else {
echo "\n can not connect";
}
} catch (Exception $ex) {
echo "\n can not insert" . microtime();
}
}
var_dump($res);
echo "ok";
我们面临的问题是,我们正试图关闭其中一台主机,除了拔掉电源,这是一种硬断电.
我们也使用MySQL-MMM进行故障转移,但这与我们面临的问题无关,但我将解释我们现在使用的程序.
1)Master-Master工作正常,server1具有虚拟IP 10.0.10.210并且正在进行写入和读取
2)我们通过拔掉电缆关闭server1,虚拟IP被移动到server2,一切正常,并且在停机约20秒后继续插入.
3)我们再次启动server1,它上升并返回虚拟IP地址,在1-2秒停机后继续插入.
这样做的问题是我们丢失了在server1停机期间发生的所有插入,如果我输入“STOP SLAVE; START SLAVE;”我收到这些错误:
[ERROR] Slave I/O: Got fatal error 1236 from master when reading data from binary log: 'Client requested master to start replication from impossible position', Error_code: 1236
如果我手动检查二进制日志,其偏移量与mysqld.log文件所说的相对应:
[root@db1 mysql]# mysqlbinlog --offset=623435 db1-mysql-bin.000001
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#121030 12:55:16 server id 1 end_log_pos 106 Start: binlog v 4, server v 5.1.61-log created 121030 12:55:16 at startup
# Warning: this binlog is either in use or was not closed properly.
ROLLBACK/*!*/;
BINLOG '
VOqPUA8BAAAAZgAAAGoAAAABAAQANS4xLjYxLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAABU6o9QEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC
'/*!*/;
ERROR: Error in Log_event::read_log_event(): 'read error', data_len: 112, event_type: 2
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
我知道二进制日志文件没有正确关闭但InnoDB不应该处理这个问题吗?当然,硬断电并不是非常罕见的,至少在我看来并不是这样.我正在运行EXT4文件系统.
到目前为止,这只是一个实验室设置,实际上我们在最先进的(未被淹没的……)数据中心运行这一点,并采取一切必要的预防措施.
非常感谢任何关于此事的光明,谢谢.
my.cnf中
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
symbolic-links=0
sync_binlog=1
# REPLICATION SETTINGS
server_id = 2
replicate-same-server-id = 0
auto-increment-increment = 2
auto-increment-offset = 2
replicate-do-db = test
binlog-ignore-db = mysql
log-bin=db2-mysql-bin
relay-log=db2-relay-log
relay-log-index=relay-log-index
[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
UPDATE
我现在已经将文件系统从EXT4切换到了XFS,它确实关注了数据的丢失,但现在我还有另一个问题,但是很小,应该很容易解决.
在我完成关闭server1的过程后,故障转移到server2,启动server1,回滚到server1.一切都保持良好的工作,server1准确地获取server2停止的位置,唯一的问题是server2停止同步server1所以它是相反的方式.
如果我跑STOP SLAVE;开始离开;它开始同步,几秒后与server1相同,但为什么不自动执行此操作?
解决方法:
复制和二进制日志记录独立于innodb,不幸的是会导致问题.
退房:http://dev.mysql.com/doc/refman/5.5/en/replication-options-binary-log.html#sysvar_sync_binlog
根据您的描述,我怀疑您的服务器的sync_binlog设置为0.将其保留为0意味着mysql将依赖文件系统来处理刷新到磁盘.实际上,这意味着binlog数据通常位于文件系统缓存中.内核会以某种间隔将其刷新到磁盘,但在电源故障的情况下,任何内容都会丢失.
将sync_binlog设置为1将强制mysql在每次提交后使用fdatasync将binlog事件刷新到文件系统.这样更安全(因为在电源故障时最多会丢失1个事务),但会产生更多的磁盘活动.基准测试并了解对您的工作负载有何影响.了解两种方案的权衡有望帮助您做出明智的决策.
希望有所帮助.