通过主从复制机制完成MySQL数据库服务迁移_MySQL
0x00 背景
业务所在机房裁撤,原业务机器也已经过保,通过MySQL主从复制机制完成MySQL数据服务的无缝迁移。
0x01 准备
1.环境:
原则上搭建mysql主从复制最好是操作系统版本、环境,MySQL版本、配置保持一致,这样可以保证MySQL主从集群的稳定性,以及减少版本和环境造成的异常,便于排查和定位问题。
由于我们涉及迁移的机器往往是很久以前上线,而且也从未有相关系统和服务升级的机制,还好这次涉及的MySQL版本比较高,与MySQL 5.6的兼容性还是比较好的,谢天谢地,谢前任。
原机器环境:
IP:A(机器已回收)
系统版本:suse 11 linux x64
mysql版本:mysql 5.5.3
配置文件路径:无
程序启动方式:/bin/sh /usr/local/mysql/bin/mysqld_safe &
新机器环境:
IP:xxxxxx B
系统版本: tlinux 1.2 64bit(centos 6.2)
mysql版本:mysql-5.6.25
配置文件路径: /etc/my.cnf
程序启动方式: /etc/init.d/mysqld start
2.安装包准备
源码包下载:
cmake:yum install cmake (2.6.4) 即可 或 下载 https://cmake.org/files/v3.3/cmake-3.3.2.tar.gz
MySQL :http://dev.mysql.com/downloads/mysql/5.6.html#downloads
0x02 MySQL安装与配置
1.安装(这里不是本文重点,如果出错了,需要根据错误分析解决)
原则上,运营环境一般推荐通过源码进行编译安装,这样才能充分利用当前机器的特性,但是由于我们以前在相同系统环境下编译安装并制作了相关部署包,所以真实安装过程就略过了。这里的安装过程是我们一般通用的安装过程:
a. yum 安装
yum install mysql mysql-server (推荐tlinux2.0,对应centos 7.0,fedora 20+)
很不幸,tilnux 1.2环境 yum安装的版本为mysql-5.1.61,老掉牙了。
b. 源码编译安装
cd mysql-5.6.25groupadd mysql
useradd -g mysql mysql -s /bin/false
mkdir -p /data/dbdata
chown mysql:mysql /data/dbdata
cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DMYSQL_DATADIR=/data/dbdata -DSYSCONFDIR=/etc/
make&&make install
cp /usr/local/mysql/support-files/my-default.cnf /etc/my.cnf
cd /usr/local/
mv mysql mysql-5.6.25 && ln -s mysql-5.6.25 mysql
cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
chmod +x /etc/init.d/mysqld
chkconfig --add mysqld
chkconfig mysqld on
初始化mysql:
/usr/local/mysql/scripts/mysql_install_db --user=mysql --basedir=/usr/local/mysql --datadir=/data/dbdata
vi /etc/profile
增加:export PATH=$PATH:/usr/local/mysql/bin
/etc/init.d/mysqld start
2.配置
旧机器:
登录 mysql服务终端:
设置server id:
set gloabl server_id=2;select @@server_id;
开启binlog:
SET SQL_LOG_BIN=1;
SET GLOBAL binlog_format = 'MIXED'; ##表结构变更以statement模式来记录,update或者delete等修改数据的语句是记录所有行的变更。
mysql> select @@server_id;
+-------------+
| @@server_id |
+-------------+
| 2 |
+-------------+
1 row in set (0.00 sec)
新机器:
vi /etc/my.cnf
log-bin = /data/dbdata/binlog/mysql-binbinlog_format = MIXED
binlog_cache_size = 4M
max_binlog_cache_size = 1024M
max_binlog_size = 1024M
expire_logs_days = 5log-slave-updates
server-id = 20151109
mysql> select @@server_id;+-------------+
| @@server_id |+-------------+
| 20151109 |
+-------------+1 row in set (0.00 sec)
0x03 数据的导出与导入
1.数据导出:
涉及的DB不多,DB的读写不频繁,导出mysql数据我们选择使用mysqldump。
因为要添加主从信息,所以需要添加-master-data=1,附带锁表操作,当表的存储引擎为InnoDB时,加了 --single-transaction 可以减少锁表的影响,准确的说只会有短时间的全局读锁,比MyISAM的锁表情况要好得多。
mysqldump -u root --default-character-set=utf8 -Y -B --set-charset --single-transaction --master-data=1 hehehehhe > /data/backup/databases/hehehehhe20151109.sql
CHANGE MASTER
-Y, --all-tablespaces
Dump all the tablespaces.
-B, --databases Dump several databases. Note the difference in usage; in
if you dump many databases at once (using the option
--databases= or --all-databases), the logs will be
Locks all tables across all databases. This is achieved
--all-databases or --databases is given.
--master-data[=#] This causes the binary log position and filename to be
appended to the output. If equal to 1, will print it as a
CHANGE MASTER command; if equal to 2, that command will
be prefixed with a comment symbol. This option will turn
--lock-all-tables on, unless --single-transaction is
specified too (in which case a global read lock is only
taken a short time at the beginning of the dump; don't
forget to read about --single-transaction below). In all
cases, any action on logs will happen at the exact moment
of the dump. Option automatically turns --lock-tables
off.
--dump-slave[=#] This causes the binary log position and filename of the
master to be appended to the dumped data output. Setting
the value to 1, will printit as a CHANGE MASTER command
in the dumped data output; if equal to 2, that command
will be prefixed with a comment symbol. This option will
turn --lock-all-tables on, unless --single-transaction is
specified too (in which case a global read lock is only
taken a short time at the beginning of the dump - don't
forget to read about --single-transaction below). In all
cases any action on logs will happen at the exact moment
of the dump.Option automatically turns --lock-tables off.
--include-master-host-port
Adds 'MASTER_HOST=
MASTER TO..' in dump produced with --dump-slave.
--single-transaction
Creates a consistent snapshot by dumping all tables in a
single transaction. Works ONLY for tables stored in
storage engines which support multiversioning (currently
only InnoDB does); the dump is NOT guaranteed to be
consistent for other storage engines. While a
--single-transaction dump is in process, to ensure a
valid dump file (correct table contents and binary log
position), no other connection should use the following
statements: ALTER TABLE, DROP TABLE, RENAME TABLE,
TRUNCATE TABLE, as consistent snapshot is not isolated
from them. Option automatically turns off --lock-tables.
--set-charset Add 'SET NAMES default_character_set' to the output.
(Defaults to on; use --skip-set-charset to disable.)
查看主从信息:
[root@WEBAPP_B_IP_HOST /data/backup/databases]#
自带切换主从同步点命令,需要注意的是添加此命令时需要将所有主从同步状态的数据库数据一同导出。
grep CHANGE /data/backup/databases/hehehehhe20151109.sql
CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=120;
2.数据导入:
新机器:
CREATE DATABASE `hehehehhe` /*!40100 DEFAULT CHARACTER SET utf8 */;
搭建主从同步后stop slave,直接通过mysql 直接导入数据,然后在start slave即可。
0x04 主从复制配置与数据的同步
1. MySQL binlog
binlog是MySQL主从复制的基础,MySQL通过binlog来记录数据库数据的变更,可用来搭建主从复制集群,也可以用mysqlbinlog来通过binlog恢复部分数据异常。
如果遇到灾难事件,应该用最近一次制作的完整备份恢复数据库,然后使用备份之后的日志文件把数据库恢复到最接近现在的可用状态。使用日志进行恢复时需要依次进行,即最早生成的日志文件要最先恢复。
常用binlog日志操作命令
1.查看所有binlog日志列表
mysql> show master logs;(新机器作为主时,binlog的信息)
[root@WEBAPP_B_IP_HOST /data/dbdata/binlog]# pwd/data/dbdata/binlog
[root@WEBAPP_B_IP_HOST /data/dbdata/binlog]# lltotal 884156-rw-rw---- 1 mysql admin 27317 Nov 9 12:41 mysql-bin.000001-rw-rw---- 1 mysql admin 1034478 Nov 9 12:41 mysql-bin.000002-rw-rw---- 1 mysql admin 531 Nov 9 12:42 mysql-bin.000003-rw-rw---- 1 mysql admin 903407219 Nov 12 00:10 mysql-bin.000004-rw-rw---- 1 mysql admin 148 Nov 9 15:08 mysql-bin.index
[root@WEBAPP_B_IP_HOST /data/dbdata/binlog]# mysql -e "show master logs;"+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000001 | 27317 |
| mysql-bin.000002 | 1034478 |
| mysql-bin.000003 | 531 |
| mysql-bin.000004 | 903407219 |
+------------------+-----------+
2.查看master状态,即最后(最新)一个binlog日志的编号名称,及其最后一个操作事件pos结束点(Position)值
mysql> show master status;(新机器作为从时,主服务器最新binlog的位置信息)
[root@WEBAPP_B_IP_HOST /data/dbdata/binlog]# mysql -e "show master status;"+------------------+-----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+-----------+--------------+------------------+-------------------+
| mysql-bin.000004 | 903407219 | | | |
+------------------+-----------+--------------+------------------+-------------------+
3.刷新log日志,自此刻开始产生一个新编号的binlog日志文件
mysql> flush logs;
mysql> flush logs;
Query OK, 0 rows affected (0.00 sec)
mysql> show master logs;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000001 | 27317 |
| mysql-bin.000002 | 1034478 |
| mysql-bin.000003 | 531 |
| mysql-bin.000004 | 903407266 |
| mysql-bin.000005 | 120 |
+------------------+-----------+5 rows in set (0.00 sec)
注:每当mysqld服务重启时,会自动执行此命令,刷新binlog日志;在mysqldump备份数据时加 -F 选项也会刷新binlog日志;
4.重置(清空)所有binlog日志
mysql> reset master;
mysql> reset master;
Query OK, 0 rows affected (0.08 sec)
mysql> show master logs;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000001 | 120 |
+------------------+-----------+1 row in set (0.00 sec)
清空当前机器的binlog。
5.清理
清除binlog
PURGE {MASTER|BINARY} LOGS TO 'log_name' //log_name不会被清除
PURGE {MASTER|BINARY} LOGS BEFORE 'date' //date不会被清除
2. 主从复制配置
1)旧机器(主A_IP)上创建主从同步帐号:
grant replication slave on *.* to 'rep'@'B_IP' identified by 'heheheh';
2)查看当前旧机器(主A_IP)的binlog状态
mysql> show master status;+------------------+----------+--------------+------------------+-------------------+| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 120 | | | |
+------------------+----------+--------------+------------------+-------------------+1 row in set (0.00 sec)
3)在新机器(B_IP)上创建主从同步
mysql> change master to master_host='A_IP',
master_user='rep',
master_password='heheheh',
master_port=3306,
master_log_file='mysql-bin.000001',
master_log_pos=120,
master_connect_retry=10;
参数详解:
master_host:主服务器的IP。
master_user:配置主服务器时建立的用户名
master_password:用户密码
master_port:主服务器mysql端口,如果未曾修改,默认即可。
master_log_file:日志文件名称,填写查看master状态时显示的Filemaster_log_pos:日志位置,填写查看master状态时显示的Positionmaster_connect_retry:重连次数
4)启动进程
mysql> start slave;
查看主从同步情况:
主要需要关注Slave_IO_Running: YES; Slave_SQL_Running: YES;Seconds_Behind_Master: 0
mysql> show slave status \G;*************************** 1. row ***************************
Slave_IO_State:
Master_Host: A_IPMaster_User: rep
Master_Port: 3306Connect_Retry: 60Master_Log_File: Tencent64-bin.000164Read_Master_Log_Pos: 107Relay_Log_File: WEBAPP_B_IP_HOST-relay-bin.000006Relay_Log_Pos: 270Relay_Master_Log_File: Tencent64-bin.000164Slave_IO_Running: YES
Slave_SQL_Running: YES
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0Last_Error:
Skip_Counter: 0Exec_Master_Log_Pos: 107Relay_Log_Space: 786Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
主从信息查看的命令:
show slave hosts \G;主机上查看从机信息
show master status\G;主机上查看状态信息
show slave status \G;从机上查看主从状态信息
0x05 存储过程与权限的导入
1.存储过程和函数的导出
由于存储过程和数据库权限信息存储在mysql库中,通过mysqldump普通参数是不会导出的。
导出存储过程: mysqldump 加 -R (或 --routines)参数即可。
-R, --routines Dump stored routines (functions and procedures).
Add 'SET @@GLOBAL.GTID_PURGED' to the output. Possible @@GLOBAL.GTID_PURGED' is added to the output. If GTIDs
statements: ALTER TABLE, DROP TABLE, RENAME TABLE,
TRUNCATE TABLE, as consistent snapshot is not isolated
单独导出存储过程等内容:
mysqldump -uroot -n -d -t -R hehehehhe > procedure_name.sql
-- MySQL dump 10.10--
-- Host: localhost Database: hehehehhe
-- ------------------------------------------------------
-- Server version 5.5.3-m3-log
后期也发现,如果在导出时mysqldump指定 --databases 会自动将原DB的创建语句添加进去,但是有的时候我们希望自己指定DB创建语句,比如要指定默认字符集为utf8,而原来的用的是latin1,这个时候我们就不需要加这个参数了。
2.数据库权限的导出与导入
数据库的权限有针对全局的也有针对特定库和表的权限,无法直接导出再导入。
主要通过查出旧机器授权过的帐号和机器IP,在通过show grants语句来获取相应权限。
mysql> SELECT CONCAT("show grants for ",user,"@",host,";") from mysql.user;
+----------------------------------------------+
| CONCAT("show grants for ",user,"@",host,";") |
+----------------------------------------------+
| show grants for hehehehhe@10.136.12.216; || show grants for hehehehhe@10.166.129.173; || show grants for hehehehhe@10.166.129.174; || show grants for adbreader@10.166.129.226; || show grants for hehehehhe@10.166.129.226; || show grants for root@127.0.0.1; || show grants for root@::1; || show grants for root@TENCENT64.site; || show grants for root@localhost; |+----------------------------------------------+9 rows in set (0.00 sec)
然后将show grants语句放到脚本中,运行脚本获取到旧机器上相关授权信息。
最后,在新机器上运行之前获得的授权信息脚本,即可导入相关权限。
注意,这里可能出现报错,数据库不存在的情况下将相关权限导入,所以在导入前需要过滤下。
0x06 数据校验与业务验证
数据校验和业务验证不是我们要讲的重点,但是是数据库迁移不可缺少的一部分。
验证数据的方式有两种:
1.查看数据记录与主从同步状态,可以简单快速判断,但是不是最准确的。
2.通过跑脚本,校验数据库下每个表的checksum值,准确,可能会有些慢。
3.通过Percona Toolkit for MySQL 工具中pt-table-checksum来进行主从校验.
0x07 常见问题分析与解决
1. MyIsam存储引擎 锁表导致服务中断,影响到业务。
之前与互娱的兄弟在RTX沟通,备份数据时MyISAM锁表时间过久导致服务出现异常,所以我们一般建议搭建专门的备机进行备份数据,以及尽量用INNODB存储引擎。
2.数据校验时,用percona的工具发现数据不一致,处理数据时发现自增ID发生变化,通过自增ID查不到指定的业务数据
数据不一致时优先使用pt-table-sync进行修复,但是这个修复方式是缺少时插入,冲突时replace,自增ID会发生变化。
建议自增ID不要作为业务属性使用。
3.占坑,未完待续,欢迎一起续写。
0x08 其他
一切皆有可能,在实验环境多去实践会降低出问题时空手无策的几率。
还好这次迁移MySQL版本比较高,要是碰到5.0或5.1那就坑死了。
感谢Percona,让一个二把手也可以保障mysql服务的稳定性。
感谢国家,感谢父母。
感谢一起讨论问题的你们。

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











Go 언어는 효율적이고 간결하며 배우기 쉬운 프로그래밍 언어입니다. 동시 프로그래밍과 네트워크 프로그래밍의 장점 때문에 개발자들이 선호합니다. 실제 개발에서 데이터베이스 작업은 필수적인 부분입니다. 이 기사에서는 Go 언어를 사용하여 데이터베이스 추가, 삭제, 수정 및 쿼리 작업을 구현하는 방법을 소개합니다. Go 언어에서는 일반적으로 사용되는 SQL 패키지, Gorm 등과 같은 타사 라이브러리를 사용하여 데이터베이스를 운영합니다. 여기서는 sql 패키지를 예로 들어 데이터베이스의 추가, 삭제, 수정 및 쿼리 작업을 구현하는 방법을 소개합니다. MySQL 데이터베이스를 사용하고 있다고 가정합니다.

Hibernate 다형성 매핑은 상속된 클래스를 데이터베이스에 매핑할 수 있으며 다음 매핑 유형을 제공합니다. Join-subclass: 상위 클래스의 모든 열을 포함하여 하위 클래스에 대한 별도의 테이블을 생성합니다. 클래스별 테이블: 하위 클래스별 열만 포함하는 하위 클래스에 대한 별도의 테이블을 만듭니다. Union-subclass: Joined-subclass와 유사하지만 상위 클래스 테이블이 모든 하위 클래스 열을 통합합니다.

Apple의 최신 iOS18, iPadOS18 및 macOS Sequoia 시스템 릴리스에는 사진 애플리케이션에 중요한 기능이 추가되었습니다. 이 기능은 사용자가 다양한 이유로 손실되거나 손상된 사진과 비디오를 쉽게 복구할 수 있도록 설계되었습니다. 새로운 기능에는 사진 앱의 도구 섹션에 '복구됨'이라는 앨범이 도입되었습니다. 이 앨범은 사용자가 기기에 사진 라이브러리에 포함되지 않은 사진이나 비디오를 가지고 있을 때 자동으로 나타납니다. "복구된" 앨범의 출현은 데이터베이스 손상으로 인해 손실된 사진과 비디오, 사진 라이브러리에 올바르게 저장되지 않은 카메라 응용 프로그램 또는 사진 라이브러리를 관리하는 타사 응용 프로그램에 대한 솔루션을 제공합니다. 사용자는 몇 가지 간단한 단계만 거치면 됩니다.

HTML은 데이터베이스를 직접 읽을 수 없지만 JavaScript 및 AJAX를 통해 읽을 수 있습니다. 단계에는 데이터베이스 연결 설정, 쿼리 보내기, 응답 처리 및 페이지 업데이트가 포함됩니다. 이 기사에서는 JavaScript, AJAX 및 PHP를 사용하여 MySQL 데이터베이스에서 데이터를 읽는 실제 예제를 제공하고 쿼리 결과를 HTML 페이지에 동적으로 표시하는 방법을 보여줍니다. 이 예제에서는 XMLHttpRequest를 사용하여 데이터베이스 연결을 설정하고 쿼리를 보내고 응답을 처리함으로써 페이지 요소에 데이터를 채우고 데이터베이스를 읽는 HTML 기능을 실현합니다.

PHP에서 데이터베이스 연결 오류를 처리하려면 다음 단계를 사용할 수 있습니다. mysqli_connect_errno()를 사용하여 오류 코드를 얻습니다. 오류 메시지를 얻으려면 mysqli_connect_error()를 사용하십시오. 이러한 오류 메시지를 캡처하고 기록하면 데이터베이스 연결 문제를 쉽게 식별하고 해결할 수 있어 애플리케이션이 원활하게 실행될 수 있습니다.

MySQLi를 사용하여 PHP에서 데이터베이스 연결을 설정하는 방법: MySQLi 확장 포함(require_once) 연결 함수 생성(functionconnect_to_db) 연결 함수 호출($conn=connect_to_db()) 쿼리 실행($result=$conn->query()) 닫기 연결( $conn->close())

PHP는 웹사이트 개발에 널리 사용되는 백엔드 프로그래밍 언어로, 강력한 데이터베이스 운영 기능을 갖추고 있으며 MySQL과 같은 데이터베이스와 상호 작용하는 데 자주 사용됩니다. 그러나 한자 인코딩의 복잡성으로 인해 데이터베이스에서 잘못된 한자를 처리할 때 문제가 자주 발생합니다. 이 기사에서는 잘못된 문자의 일반적인 원인, 솔루션 및 특정 코드 예제를 포함하여 데이터베이스에서 중국어 잘못된 문자를 처리하기 위한 PHP의 기술과 사례를 소개합니다. 문자가 왜곡되는 일반적인 이유는 잘못된 데이터베이스 문자 집합 설정 때문입니다. 데이터베이스를 생성할 때 utf8 또는 u와 같은 올바른 문자 집합을 선택해야 합니다.

Golang의 데이터베이스 콜백 기능을 사용하면 다음을 달성할 수 있습니다. 지정된 데이터베이스 작업이 완료된 후 사용자 정의 코드를 실행합니다. 추가 코드를 작성하지 않고도 별도의 함수를 통해 사용자 정의 동작을 추가할 수 있습니다. 삽입, 업데이트, 삭제, 쿼리 작업에 콜백 함수를 사용할 수 있습니다. 콜백 함수를 사용하려면 sql.Exec, sql.QueryRow, sql.Query 함수를 사용해야 합니다.
