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
— 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
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
只有找不到*.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

MySQL 느린 쿼리를 최적화하려면 SlowQueryLog 및 Performance_Schema를 사용해야합니다. 1. SlowQueryLog 및 Set Stresholds를 사용하여 느린 쿼리를 기록합니다. 2. Performance_schema를 사용하여 쿼리 실행 세부 정보를 분석하고 성능 병목 현상을 찾고 최적화하십시오.

MySQL 및 SQL은 개발자에게 필수적인 기술입니다. 1.MySQL은 오픈 소스 관계형 데이터베이스 관리 시스템이며 SQL은 데이터베이스를 관리하고 작동하는 데 사용되는 표준 언어입니다. 2.MYSQL은 효율적인 데이터 저장 및 검색 기능을 통해 여러 스토리지 엔진을 지원하며 SQL은 간단한 문을 통해 복잡한 데이터 작업을 완료합니다. 3. 사용의 예에는 기본 쿼리 및 조건 별 필터링 및 정렬과 같은 고급 쿼리가 포함됩니다. 4. 일반적인 오류에는 구문 오류 및 성능 문제가 포함되며 SQL 문을 확인하고 설명 명령을 사용하여 최적화 할 수 있습니다. 5. 성능 최적화 기술에는 인덱스 사용, 전체 테이블 스캔 피하기, 조인 작업 최적화 및 코드 가독성 향상이 포함됩니다.

MySQL 비동기 마스터 슬레이브 복제는 Binlog를 통한 데이터 동기화를 가능하게하여 읽기 성능 및 고 가용성을 향상시킵니다. 1) 마스터 서버 레코드는 Binlog로 변경됩니다. 2) 슬레이브 서버는 I/O 스레드를 통해 Binlog를 읽습니다. 3) 서버 SQL 스레드는 데이터를 동기화하기 위해 Binlog를 적용합니다.

MySQL은 오픈 소스 관계형 데이터베이스 관리 시스템입니다. 1) 데이터베이스 및 테이블 작성 : CreateAbase 및 CreateTable 명령을 사용하십시오. 2) 기본 작업 : 삽입, 업데이트, 삭제 및 선택. 3) 고급 운영 : 가입, 하위 쿼리 및 거래 처리. 4) 디버깅 기술 : 확인, 데이터 유형 및 권한을 확인하십시오. 5) 최적화 제안 : 인덱스 사용, 선택을 피하고 거래를 사용하십시오.

MySQL의 설치 및 기본 작업에는 다음이 포함됩니다. 1. MySQL 다운로드 및 설치, 루트 사용자 비밀번호를 설정하십시오. 2. SQL 명령을 사용하여 CreateAbase 및 CreateTable과 같은 데이터베이스 및 테이블을 만듭니다. 3. CRUD 작업을 실행하고 삽입, 선택, 업데이트, 명령을 삭제합니다. 4. 성능을 최적화하고 복잡한 논리를 구현하기 위해 인덱스 및 저장 절차를 생성합니다. 이 단계를 사용하면 MySQL 데이터베이스를 처음부터 구축하고 관리 할 수 있습니다.

innodbbufferpool은 데이터와 색인 페이지를 메모리에로드하여 MySQL 데이터베이스의 성능을 향상시킵니다. 1) 데이터 페이지가 버퍼 풀에로드되어 디스크 I/O를 줄입니다. 2) 더러운 페이지는 정기적으로 디스크로 표시되고 새로 고침됩니다. 3) LRU 알고리즘 관리 데이터 페이지 제거. 4) 읽기 메커니즘은 가능한 데이터 페이지를 미리로드합니다.

MySQL은 설치가 간단하고 강력하며 데이터를 쉽게 관리하기 쉽기 때문에 초보자에게 적합합니다. 1. 다양한 운영 체제에 적합한 간단한 설치 및 구성. 2. 데이터베이스 및 테이블 작성, 삽입, 쿼리, 업데이트 및 삭제와 같은 기본 작업을 지원합니다. 3. 조인 작업 및 하위 쿼리와 같은 고급 기능을 제공합니다. 4. 인덱싱, 쿼리 최적화 및 테이블 파티셔닝을 통해 성능을 향상시킬 수 있습니다. 5. 데이터 보안 및 일관성을 보장하기위한 지원 백업, 복구 및 보안 조치.

전체 테이블 스캔은 MySQL에서 인덱스를 사용하는 것보다 빠를 수 있습니다. 특정 사례는 다음과 같습니다. 1) 데이터 볼륨은 작습니다. 2) 쿼리가 많은 양의 데이터를 반환 할 때; 3) 인덱스 열이 매우 선택적이지 않은 경우; 4) 복잡한 쿼리시. 쿼리 계획을 분석하고 인덱스 최적화, 과도한 인덱스를 피하고 정기적으로 테이블을 유지 관리하면 실제 응용 프로그램에서 최상의 선택을 할 수 있습니다.


핫 AI 도구

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

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

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

Clothoff.io
AI 옷 제거제

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

인기 기사

뜨거운 도구

안전한 시험 브라우저
안전한 시험 브라우저는 온라인 시험을 안전하게 치르기 위한 보안 브라우저 환경입니다. 이 소프트웨어는 모든 컴퓨터를 안전한 워크스테이션으로 바꿔줍니다. 이는 모든 유틸리티에 대한 액세스를 제어하고 학생들이 승인되지 않은 리소스를 사용하는 것을 방지합니다.

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

Atom Editor Mac 버전 다운로드
가장 인기 있는 오픈 소스 편집기

SublimeText3 영어 버전
권장 사항: Win 버전, 코드 프롬프트 지원!

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

뜨거운 주제



