mysql – 断电测试后,InnoDB Master-Master复制不一致

下午的男士,

我目前正在使用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个事务),但会产生更多的磁盘活动.基准测试并了解对您的工作负载有何影响.了解两种方案的权衡有望帮助您做出明智的决策.

希望有所帮助.

上一篇:linux – 基于mysql语句的复制 – 不安全的语句


下一篇:mysql – 查询分析显示“等待查询缓存锁定”,但query_cache_size为0