Lar*_*ars 6 mysql innodb replication php failover
下午各位大佬
我目前正在使用 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";
Run Code Online (Sandbox Code Playgroud)
我们面临的问题是,我们试图关闭一台主机,只使用拔掉电源,即硬断电。
我们也将 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
Run Code Online (Sandbox Code Playgroud)
如果我使用与 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*/;
Run Code Online (Sandbox Code Playgroud)
我知道二进制日志文件没有正确关闭,但 InnoDB 不应该处理这个问题吗?当然,硬关机并不是一件非常罕见的事情,至少在我看来不是。我正在运行 EXT4 文件系统。
到目前为止,这只是一个实验室设置,实际上我们在最先进的(不是淹没......)数据中心运行它,并采取了所有必要的预防措施。
任何关于此事的线索将不胜感激,谢谢。
我的.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
Run Code Online (Sandbox Code Playgroud)
更新
我现在已经将文件系统从 EXT4 切换到 XFS,它确实解决了数据丢失的问题,但现在我有另一个问题,但问题很小,应该很容易解决。
在我完成关闭 server1 的过程后,故障转移到 server2,启动 server1,回滚到 server1。一切都保持出色,并且 server1 准确地从 server2 停止的地方恢复,唯一的问题是 server2 停止同步 server1,所以情况正好相反。
如果我运行 STOP SLAVE; 启动从机;它开始同步,几秒钟后与 server1 相同,但为什么不自动执行此操作?
经过一番思考,我发现从站无法区分静默(空闲)主站和崩溃的主站,除非给出错误,因此 TCP 连接将保持在线状态,直到达到从站默认 TCP 超时。
在我的盒子上,这是默认设置
[root@db1 ~]# sysctl -e net.ipv4.tcp_keepalive_time
net.ipv4.tcp_keepalive_time = 7200
Run Code Online (Sandbox Code Playgroud)
所以我用它来解决
echo 30 > /proc/sys/net/ipv4/tcp_keepalive_time
echo 2 > /proc/sys/net/ipv4/tcp_keepalive_probes
echo 1 > /proc/sys/net/ipv4/tcp_keepalive_intvl
Run Code Online (Sandbox Code Playgroud)
这使得它每 30 秒发送一次 SYN 包以查看连接是否仍在回复,并且会更快地启动同步方式。不要忘记重新启动 MySQL 进程,以便重新打开套接字,并将其添加到 rc 脚本中,以便在重新启动后保留设置。
为此需要调整很多旋钮,因此这里有一个包含有关该主题的更多信息的 URL。 http://dom.as/2006/09/12/mysql-tcp-network-tuning/
如果您对如何设置感兴趣,请阅读此处。 http://mute.nu/2012/how-to-set-up-a-2-node-apache-and-mysql-fail-over-environment/
总而言之,将 MySQL 数据目录放在 XFS 上并调整 TCP 保持活动设置,一切就完成了。
归档时间: |
|
查看次数: |
2059 次 |
最近记录: |