Home Database Mysql Tutorial MySQL Multi-Master实现方式

MySQL Multi-Master实现方式

Mar 13, 2017 pm 01:46 PM
mysql content accomplish Way

MySQL Mutil-Master Replication喊了很久了,但是MySQL一直没有去,虽然在MySQL源码中有注释将实现Multi-Master,mi结构体也为Multi-Master做好了准备,但是却一直不见MySQL发布。

但是Multi-Master –> Slave的Repliction确实非常有用,例如一台集中备份机备份所有Master的数据。

实现Multi-Master有几种思路:
1. 修改MySQL源码:修改sql_yacc.yy, sql_lex.cc支持多Master的CHANGE MASTER TO语法,然后修改slave相关的slave.cc,支持开启多个Slave, 将slave io/ slave thread线程扩展为一个slave_list。
2. 利用mysqlbinlog之类的工具,远程注册到Master获取binlog,导入本地Slave服务器。

从效率看,肯定第一种方式效率高,但是风险太大了,并且MySQL版本更新,可能需要变动自己的代码以适应新的MySQL Source, MySQL官方的实现方式肯定是第一种,从源码中的注释可以看出他们的设计思路。但是他们考虑的问题可能是多个Master复制如何处理冲突等异常,因而迟迟不发布。

为了避免过多的入侵MySQL,我采用第二种方式,用一个脚本或者程序等等,去调用mysqlbinlog,用-R远程请求到–to-last-log,然后稍微修改一下啊mysqlbinlog的源码,在日志切换后计数一下,在输出文件末尾打上切换日志的个数,例如:

insert into a values (8)/*!*/;
# at 1070#110114 16:16:11 server id 3  end_log_pos 1097 	Xid = 36COMMIT/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;-- Rorate binlog count: 1
Copy after login

— Rorate binlog count: 1就是日志切换信息,表示切换了一次日志(即传入Master的日志号没有用完)然后tail末尾的end_pos来查看本次同步到哪里了,写到*.info的文件中。

我的脚本需要配置一个multi_master.conf文件,配好每个Master的信息,例如:

#cat multi_master.conf 
[master1]MASTER_HOST=1.2.3.4
MASTER_USER=plx
MASTER_PASSWORD=plx
MASTER_PORT=3306MASTER_LOG_NAME=mysql-bin
MASTER_LOG_IDX=000002
MASTER_LOG_POS=521RELAY_LOG_DIR=/tmp/RELAY_LOG_NAME=1-relay-bin
 [master2]MASTER_HOST=2.3.4.5
MASTER_USER=plx
MASTER_PASSWORD=plx
MASTER_PORT=3306MASTER_LOG_NAME=mysql-bin
MASTER_LOG_IDX=000002
MASTER_LOG_POS=581RELAY_LOG_DIR=/tmp/RELAY_LOG_NAME=2-relay-bin
 [slave]SLAVE_USER=plx
SLAVE_PASSWORD=plx
Copy after login

SLAVE默认导入本地,所以没有提供主机选项。
配置文件的含义是,定义了master1和master2两个Master,名称其实只要不是slave都行,[slave]中定义了本地导入的用户名和密码。
特有的参数我解释下,没解释的跟MySQL一样,
MASTER_LOG_NAME和MASTER_LOG_IDX组成MySQL中的Master_log_file,RELAY_LOG_DIR表示取回的binlog文件放哪个目录,RELAY_LOG_NAME是Relay文件的文件名,会加上标号,跟MySQL一样,这个脚本会自动处理。
一旦执行过一次,就会生成master1.info之类的文件,来表示当前同步到哪里了,例如下面这个例子:

MASTER_LOG_POS=1482NAME=master1
MASTER_USER=plx
RELAY_LOG_NAME=1-relay-bin
MASTER_LOG_IDX=2MASTER_HOST=1.2.3.4
MASTER_LOG_NAME=mysql-bin
MASTER_PORT=3306RELAY_LOG_DIR=/tmp/MASTER_PASSWORD=plx
RELAY_LOG_IDX=3
Copy after login

只有找不到*.info的时候,才会使用multi_master.conf。

现在每次调度multi_master_repl.pl都只会运行一次,可以不断的调度multi_master_repl.pl,因为还没有完全搞定KILL信号在Perl脚本的处理,用C重写后会解决,不能暴力kill -9,会导致不知道复制到哪里了。

这是下载地址,切勿用在生产环境,这只是个验证想法的程序。

Note: There is a file embedded within this post, please visit this post to download the file.

下一步我想用C重新实现,在mysqlbinlog源码基础上修改,获取到的日志直接写入到sock或直接导入远程mysql,避免多写一次文件,也欢迎提供新思路。

这是一次执行的日志:

#./multi_master_repl.pl 
(DEBUG) Enter: get_config()
	Info: begin
	(DEBUG) get_config --> master1
	(DEBUG) get_config --> multi_master.conf --> master1:MASTER_HOST=1.2.3.4
	(DEBUG) get_config --> multi_master.conf --> master1:MASTER_USER=plx
	(DEBUG) get_config --> multi_master.conf --> master1:MASTER_PASSWORD=plx
	(DEBUG) get_config --> multi_master.conf --> master1:MASTER_PORT=3306
	(DEBUG) get_config --> multi_master.conf --> master1:MASTER_LOG_NAME=mysql-bin
	(DEBUG) get_config --> multi_master.conf --> master1:MASTER_LOG_IDX=000002
	(DEBUG) get_config --> multi_master.conf --> master1:MASTER_LOG_POS=521
	(DEBUG) get_config --> multi_master.conf --> master1:RELAY_LOG_DIR=/tmp/
	(DEBUG) get_config --> multi_master.conf --> master1:RELAY_LOG_NAME=1-relay-bin
	(DEBUG) get_config --> Found master1.info, Read it
	(DEBUG) get_config --> master1.info --> master1:MASTER_LOG_POS=1097
	(DEBUG) get_config --> master1.info --> master1:NAME=master1
	(DEBUG) get_config --> master1.info --> master1:MASTER_USER=plx
	(DEBUG) get_config --> master1.info --> master1:RELAY_LOG_NAME=1-relay-bin
	(DEBUG) get_config --> master1.info --> master1:MASTER_LOG_IDX=2
	(DEBUG) get_config --> master1.info --> master1:MASTER_HOST=1.2.3.4
	(DEBUG) get_config --> master1.info --> master1:MASTER_LOG_NAME=mysql-bin
	(DEBUG) get_config --> master1.info --> master1:MASTER_PORT=3306
	(DEBUG) get_config --> master1.info --> master1:RELAY_LOG_DIR=/tmp/
	(DEBUG) get_config --> master1.info --> master1:MASTER_PASSWORD=plx
	(DEBUG) get_config --> master1.info --> master1:RELAY_LOG_IDX=2
	(DEBUG) get_config --> Push[master1] to Master_Info_List
	(DEBUG) get_config --> master2
	(DEBUG) get_config --> multi_master.conf --> master2:MASTER_HOST=2.3.4.5
	(DEBUG) get_config --> multi_master.conf --> master2:MASTER_USER=plx
	(DEBUG) get_config --> multi_master.conf --> master2:MASTER_PASSWORD=plx
	(DEBUG) get_config --> multi_master.conf --> master2:MASTER_PORT=3306
	(DEBUG) get_config --> multi_master.conf --> master2:MASTER_LOG_NAME=mysql-bin
	(DEBUG) get_config --> multi_master.conf --> master2:MASTER_LOG_IDX=000002
	(DEBUG) get_config --> multi_master.conf --> master2:MASTER_LOG_POS=581
	(DEBUG) get_config --> multi_master.conf --> master2:RELAY_LOG_DIR=/tmp/
	(DEBUG) get_config --> multi_master.conf --> master2:RELAY_LOG_NAME=2-relay-bin
	(DEBUG) get_config --> Found master2.info, Read it
	(DEBUG) get_config --> master2.info --> master2:MASTER_LOG_POS=1541
	(DEBUG) get_config --> master2.info --> master2:NAME=master2
	(DEBUG) get_config --> master2.info --> master2:MASTER_USER=plx
	(DEBUG) get_config --> master2.info --> master2:RELAY_LOG_NAME=2-relay-bin
	(DEBUG) get_config --> master2.info --> master2:MASTER_LOG_IDX=2
	(DEBUG) get_config --> master2.info --> master2:MASTER_HOST=2.3.4.5
	(DEBUG) get_config --> master2.info --> master2:MASTER_LOG_NAME=mysql-bin
	(DEBUG) get_config --> master2.info --> master2:MASTER_PORT=3306
	(DEBUG) get_config --> master2.info --> master2:RELAY_LOG_DIR=/tmp/
	(DEBUG) get_config --> master2.info --> master2:MASTER_PASSWORD=plx
	(DEBUG) get_config --> master2.info --> master2:RELAY_LOG_IDX=2
	(DEBUG) get_config --> Push[master2] to Master_Info_List
	(DEBUG) get_config --> multi_master.conf --> slave:SLAVE_USER=plx
	(DEBUG) get_config --> multi_master.conf --> slave:SLAVE_PASSWORD=plx
(DEBUG) Enter: get_config()
	Info: exit
(DEBUG) Enter: create_slave_threads()
	Info: begin
	(DEBUG) create_slave_threads --> Creating run_slave Threads...
(DEBUG) Enter: run_slave()
	Info: begin [tid: 1]
	(DEBUG) run_slave(0) --> NO KILL SIGNAL --> g_is_killed =>0
	(DEBUG) run_slave --> mysqlbinlog: ./mysqlbinlog -h1.2.3.4 -uplx -pplx -R -t --start-position=1097 mysql-bin.000002 > /tmp/1-relay-bin.000002
Warning: ./mysqlbinlog: unknown variable 'loose_default-character-set=utf8'
	(DEBUG) run_slave(0) --> NO KILL SIGNAL --> g_is_killed =>0
(DEBUG) Enter: import_to_slave()
	Info: begin [Param: p_master_idx=>0]
	(DEBUG) import_to_slave(0) --> NO KILL SIGNAL --> g_is_killed =>0
	(DEBUG) import_to_slave(0) --> Importing Relay Log /tmp/1-relay-bin.000002 To Slave...
	(DEBUG) create_slave_threads --> Created 2 run_slave Threads
(DEBUG) Enter: run_slave()
	Info: begin [tid: 2]
	(DEBUG) run_slave(1) --> NO KILL SIGNAL --> g_is_killed =>0
	(DEBUG) run_slave --> mysqlbinlog: ./mysqlbinlog -h2.3.4.5 -uplx -pplx -R -t --start-position=1541 mysql-bin.000002 > /tmp/2-relay-bin.000002
Warning: ./mysqlbinlog: unknown variable 'loose_default-character-set=utf8'
	(DEBUG) run_slave(1) --> NO KILL SIGNAL --> g_is_killed =>0
(DEBUG) Enter: import_to_slave()
	Info: begin [Param: p_master_idx=>1]
	(DEBUG) import_to_slave(1) --> NO KILL SIGNAL --> g_is_killed =>0
	(DEBUG) import_to_slave(1) --> Importing Relay Log /tmp/2-relay-bin.000002 To Slave...
(DEBUG) Enter: update_master_info()
	Info: begin [Param: p_master_idx=>0]
(DEBUG) Enter: update_master_info()
	Info: begin [Param: p_master_idx=>1]
	(DEBUG) update_master_info(0) --> Now Master-Log is mysql-bin.000002 Pos is 1482
(DEBUG) Enter: update_master_info_file()
	Info: begin [Param: p_master_idx=>0]
	(DEBUG) update_master_info_file(0) --> NO KILL SIGNAL --> g_is_killed =>0
	(DEBUG) update_master_info_file(0) --> Writing master1.info --> MASTER_LOG_POS=1482
	(DEBUG) update_master_info_file(0) --> Writing master1.info --> NAME=master1
	(DEBUG) update_master_info_file(0) --> Writing master1.info --> MASTER_USER=plx
	(DEBUG) update_master_info_file(0) --> Writing master1.info --> RELAY_LOG_NAME=1-relay-bin
	(DEBUG) update_master_info_file(0) --> Writing master1.info --> MASTER_LOG_IDX=2
	(DEBUG) update_master_info_file(0) --> Writing master1.info --> MASTER_HOST=1.2.3.4
	(DEBUG) update_master_info_file(0) --> Writing master1.info --> MASTER_LOG_NAME=mysql-bin
	(DEBUG) update_master_info_file(0) --> Writing master1.info --> MASTER_PORT=3306
	(DEBUG) update_master_info_file(0) --> Writing master1.info --> RELAY_LOG_DIR=/tmp/
	(DEBUG) update_master_info_file(0) --> Writing master1.info --> MASTER_PASSWORD=plx
	(DEBUG) update_master_info_file(0) --> Writing master1.info --> RELAY_LOG_IDX=3
	(DEBUG) update_master_info_file(0) --> Created master1.info
(DEBUG) Enter: update_master_info_file(0)
	Info: exit
(DEBUG) Enter: update_master_info(0)
	Info: exit
(DEBUG) Enter: import_to_slave(0)
	Info: exit
(DEBUG) Enter: run_slave(0)
	Info: exit
	(DEBUG) update_master_info(1) --> Now Master-Log is mysql-bin.000002 Pos is 2120
(DEBUG) Enter: update_master_info_file()
	Info: begin [Param: p_master_idx=>1]
	(DEBUG) update_master_info_file(1) --> NO KILL SIGNAL --> g_is_killed =>0
	(DEBUG) update_master_info_file(1) --> Writing master2.info --> MASTER_LOG_POS=2120
	(DEBUG) update_master_info_file(1) --> Writing master2.info --> NAME=master2
	(DEBUG) update_master_info_file(1) --> Writing master2.info --> MASTER_USER=plx
	(DEBUG) update_master_info_file(1) --> Writing master2.info --> RELAY_LOG_NAME=2-relay-bin
	(DEBUG) update_master_info_file(1) --> Writing master2.info --> MASTER_LOG_IDX=2
	(DEBUG) update_master_info_file(1) --> Writing master2.info --> MASTER_HOST=2.3.4.5
	(DEBUG) update_master_info_file(1) --> Writing master2.info --> MASTER_LOG_NAME=mysql-bin
	(DEBUG) update_master_info_file(1) --> Writing master2.info --> MASTER_PORT=3306
	(DEBUG) update_master_info_file(1) --> Writing master2.info --> RELAY_LOG_DIR=/tmp/
	(DEBUG) update_master_info_file(1) --> Writing master2.info --> MASTER_PASSWORD=plx
	(DEBUG) update_master_info_file(1) --> Writing master2.info --> RELAY_LOG_IDX=3
	(DEBUG) update_master_info_file(1) --> Created master2.info
(DEBUG) Enter: update_master_info_file(1)
	Info: exit
(DEBUG) Enter: update_master_info(1)
	Info: exit
(DEBUG) Enter: import_to_slave(1)
	Info: exit
(DEBUG) Enter: run_slave(1)
	Info: exit
(DEBUG) Enter: create_slave_threads()
	Info: exit
Copy after login
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Roblox: Bubble Gum Simulator Infinity - How To Get And Use Royal Keys
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Nordhold: Fusion System, Explained
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Mandragora: Whispers Of The Witch Tree - How To Unlock The Grappling Hook
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Hot Topics

Java Tutorial
1670
14
PHP Tutorial
1274
29
C# Tutorial
1256
24
Laravel Introduction Example Laravel Introduction Example Apr 18, 2025 pm 12:45 PM

Laravel is a PHP framework for easy building of web applications. It provides a range of powerful features including: Installation: Install the Laravel CLI globally with Composer and create applications in the project directory. Routing: Define the relationship between the URL and the handler in routes/web.php. View: Create a view in resources/views to render the application's interface. Database Integration: Provides out-of-the-box integration with databases such as MySQL and uses migration to create and modify tables. Model and Controller: The model represents the database entity and the controller processes HTTP requests.

MySQL and phpMyAdmin: Core Features and Functions MySQL and phpMyAdmin: Core Features and Functions Apr 22, 2025 am 12:12 AM

MySQL and phpMyAdmin are powerful database management tools. 1) MySQL is used to create databases and tables, and to execute DML and SQL queries. 2) phpMyAdmin provides an intuitive interface for database management, table structure management, data operations and user permission management.

MySQL vs. Other Programming Languages: A Comparison MySQL vs. Other Programming Languages: A Comparison Apr 19, 2025 am 12:22 AM

Compared with other programming languages, MySQL is mainly used to store and manage data, while other languages ​​such as Python, Java, and C are used for logical processing and application development. MySQL is known for its high performance, scalability and cross-platform support, suitable for data management needs, while other languages ​​have advantages in their respective fields such as data analytics, enterprise applications, and system programming.

Laravel framework installation method Laravel framework installation method Apr 18, 2025 pm 12:54 PM

Article summary: This article provides detailed step-by-step instructions to guide readers on how to easily install the Laravel framework. Laravel is a powerful PHP framework that speeds up the development process of web applications. This tutorial covers the installation process from system requirements to configuring databases and setting up routing. By following these steps, readers can quickly and efficiently lay a solid foundation for their Laravel project.

Explain the purpose of foreign keys in MySQL. Explain the purpose of foreign keys in MySQL. Apr 25, 2025 am 12:17 AM

In MySQL, the function of foreign keys is to establish the relationship between tables and ensure the consistency and integrity of the data. Foreign keys maintain the effectiveness of data through reference integrity checks and cascading operations. Pay attention to performance optimization and avoid common errors when using them.

Compare and contrast MySQL and MariaDB. Compare and contrast MySQL and MariaDB. Apr 26, 2025 am 12:08 AM

The main difference between MySQL and MariaDB is performance, functionality and license: 1. MySQL is developed by Oracle, and MariaDB is its fork. 2. MariaDB may perform better in high load environments. 3.MariaDB provides more storage engines and functions. 4.MySQL adopts a dual license, and MariaDB is completely open source. The existing infrastructure, performance requirements, functional requirements and license costs should be taken into account when choosing.

What software is better for yi framework? Recommended software for yi framework What software is better for yi framework? Recommended software for yi framework Apr 18, 2025 pm 11:03 PM

Abstract of the first paragraph of the article: When choosing software to develop Yi framework applications, multiple factors need to be considered. While native mobile application development tools such as XCode and Android Studio can provide strong control and flexibility, cross-platform frameworks such as React Native and Flutter are becoming increasingly popular with the benefits of being able to deploy to multiple platforms at once. For developers new to mobile development, low-code or no-code platforms such as AppSheet and Glide can quickly and easily build applications. Additionally, cloud service providers such as AWS Amplify and Firebase provide comprehensive tools

SQL vs. MySQL: Clarifying the Relationship Between the Two SQL vs. MySQL: Clarifying the Relationship Between the Two Apr 24, 2025 am 12:02 AM

SQL is a standard language for managing relational databases, while MySQL is a database management system that uses SQL. SQL defines ways to interact with a database, including CRUD operations, while MySQL implements the SQL standard and provides additional features such as stored procedures and triggers.

See all articles