-
https://dev.mysql.com/blog-archive/docker-compose-setup-for-innodb-cluster/
RealMySQL 스터디를 진행하면서 InnoDB 클러스터를 직접 구축하고 테스트해보고 싶었지만, 실습용으로 사용할 분산된 서버환경을 어떻게 구성해야 할지 막막했다. 그러던 중 MySQL 공식 개발자 블로그 페이지에 실제 분산된 머신 상에서는 아니지만 Docker-Compose 를 통해 로컬에 InnoDB 클러스터를 구축하는 예제가 있어 해당 포스트를 보며 클러스터를 로컬에 구축해 보았다.
* 포스트에는 해당 예시는 도커라이징된 환경에서 어떻게 로컬에 InnoDB 클러스터링을 구성 할수 있을지에 대한 예시일 뿐, 각 MySQL 서버 보안 설정이나 네트워크 단의 설정이 빠져있기 때문에 실제 프로덕션 환경에 바로 적용하기에는 적합하지 않다는 설명이 나와있다.
하지만 스터디에서 실습용으로 클러스터를 어떻게 구성하고 각 요소들이 어떻게 연결되는지 그리고 그룹 복제를 직접 테스트 해보기에는 적합 할 것 같아 해당 포스트를 보며 실습을 진행했다.
테스트 진행 코드
https://github.com/Yesung-Han/docker-compose-innodb-cluster/tree/main
클러스터 구성
먼저 클러스터에 참여하는 멤버는 총 3개 서버로 구성은 다음과 같다.
프라이머리 서버 : mysql-server-1
image: mysql/mysql-server:8.0.12ports: 3301:3306
세컨더리 서버 1 : mysql-server-2
image: mysql/mysql-server:8.0.12
ports: 3302:3306세컨더리 서버 2 : mysql-server-3
image: mysql/mysql-server:8.0.12
ports: 3303:3306클러스터 구성 요소 중 MySQL Router와 MySQL Shell 은 다음과 같다.
mysql-shell
환경: oraclelinux:7
mysql-shell-8.0.13-1.el7.x86_64.rpm 설치 후 사용mysql-router
image: mysql/mysql-router:8.0
ports: 6446:6446MySQL 서버 구성 살펴보기
공식 예제에 사용되는 서버구성을 살펴보면 책에 나온 InnoDB 클러스터를 구성하기 위한 그룹 복제 요구사항 옵션들을 확인 할 수 있었다.
docker-compose.yml 파일에 각 서버들의 실행 옵션이 다음과 같이 구성되어 있는데 이를 살펴 보면
command: ["mysqld","--server_id=2","--binlog_checksum=NONE","--gtid_mode=ON","--enforce_gtid_consistency=ON","--log_bin","--log_slave_updates=ON","--master_info_repository=TABLE","--relay_log_info_repository=TABLE","--transaction_write_set_extraction=XXHASH64","--user=mysql","--skip-host-cache","--skip-name-resolve", "--default_authentication_plugin=mysql_native_password"]
그룹 복제 요구사항
1. 각 서버는 고유한 서버아이디 사용
--server_id=2
2. 바이너리 로그가 활성화 되어야 한다.
--log_bin
3. ROW 포멧의 바이너리 로그 사용해야한다.
--log_bin 일때 디폴트가 ROW 포멧
4. log_slave_updates 활성화 해야한다.
그룹 복제에서는 잠재적으로 모든 멤버들이 쓰기를 수행하는 프라이머리 서버가 될 수 있으므로, 각 멤버들은 그룹에서 발생한 트랜잭션을 모두 각자의 바이너리 로그에 기록해두고 있어야 한다.
해당 옵션이 ON일 경우 마스터 서버에서 발생한 변경 사항을 복제(slave) 서버의 바이너리 로그에도 기록하게된다.
--log_slave_updates=ON
5. MySQL 8.0.20 버전까지는 그룹복제에서 바이너리 로그 체크섬 기능을 지원하지 않으므로 binlog_checksum 값을 NONE으로 설정 해야 한다.
binlog_checksum 값을 NONE으로 설정 할 경우 체크섬 검사를 비활성화하게 된다. 바이너리 로그 파일에는 체크섬이 생성되지 않고, 데이터의 무결성은 검사되지 않게된다.
--binlog_checksum=NONE
6. 그룹복제는 GTID를 사용한다.
--gtid_mode=ON
--enforce_gtid_consistency=ON
# GTID (Global Transaction ID)란?
GTID는 MySQL 복제(Replication)에서 사용되는 고유 식별자로, 그룹에 참여하는 멤버들끼리 전역적인 트랜잭션 아이디를 만들어 사용하고 싶을 경우 설정한다. 이렇게 멤버들끼리 Global한 트랜잭션 아이디를 만들어 사용할 경우, 기존 바이너리 로그 파일의 위치 기반 복제보다 복제 내구성을 강화 할 수 있다.
GTID는 마스터 서버에서 생성되며, 복제 서버는 이를 사용하여 정확한 트랜잭션 복제를 수행하게 된다.
-enforce-gtid-consistency 옵션을 사용하면 MySQL 서버가 실행되는 동안 GTID 일관성을 강제화한다. 이 옵션이 활성화되면 GTID 일관성을 검사하여 GTID가 일치하지 않는 트랜잭션을 거부하고, 복제의 일관성을 해칠 수 있는 쿼리를 허용하지 않음으로 일관성을 유지한다.
복제의 일관성을 해칠 수 있는 쿼리유형으로는 소스 서버에서 레플리카 서버로 복제되어 적용될 때 단일 트랜잭션 으로 처리되지 않을 수도 있는 것들이 있는데 다음과 같은 쿼리들은 안전하지 않다.
- 트랜잭션을 지원하는 테이블과 지원하지 않는 테이블을 함께 변경하는 쿼리 혹은 트랜잭션
- CREATE TABLE . . SELECT 구문
- 트랜잭션 내에서 CREATE TEMPORARY TABLE, DROP TEMPORARY TABLE 구문 사용단일트랜잭션으로 처리되지 않을 수 있는 쿼리가 위험한 이유는 GTID가 트랜잭션 단위로 올바르게 할당돼야 복제가 정상적으로 원자적으로 동작하기 때문이다.
만약 소스서버에서 하나의 작업이 여러 트랜잭션으로 쪼개져 각각 다른 GTID가 생성 된다면, 원자적으로 이루어져야 하는 어떤 작업이 레플리카 서버에서는 원자적으로 이루어지지 않을 수 있다. 이러한 트랜잭션 쪼개짐은 곧 데이터의 일관성을 헤치는 원인이 된다.
7. 그룹복제에서 복제 관련 메타데이터는 데이터 일관성을 위해 테이블에 저장되어야 한다.
--master_info_repository=TABLE
8. 트랜잭션 WriteSet 설정
그룹복제에서 트랜잭션 충돌을 탐지 할때, 그 인증 단계에서 WriteSet이 사용되기 때문에 WriteSet을 추출하는 알고리즘을 지정해주어야 하는데 그룹복제에서는 XXHASH64 알고리즘을 사용한다.
--transaction_write_set_extraction=XXHASH64
그 외의 서버 구성 요구사항들은 아래 공식 문서에서 확인이 가능하다.
https://dev.mysql.com/doc/refman/8.0/en/group-replication-requirements.html
MySQL-Shell 에서 하는 일 살펴보기
mysql-shell 컨테이너가 시작될때 실행되는 파일인
compose/mysql-shell/run.sh 파일을 보면
if [ "$MYSQLSH_SCRIPT" ]; then mysqlsh "$MYSQL_USER@$MYSQL_HOST:$MYSQL_PORT" --dbpassword="$MYSQL_PASSWORD" -f "$MYSQLSH_SCRIPT" || true fi if [ "$MYSQL_SCRIPT" ]; then mysqlsh "$MYSQL_USER@$MYSQL_HOST:$MYSQL_PORT" --dbpassword="$MYSQL_PASSWORD" --sql -f "$MYSQL_SCRIPT" || true fi
MYSQLSH_SCRIPT 와 MYSQL_SCRIPT 로 등록된 파일을 설치한 mysqlsh로 실행하는것을 확인 할 수 있다.
mysql-shell.env 파일을 확인 해보면 각각 어떤 파일을 실행하는 지 확인 할수 있다.
MYSQLSH_SCRIPT=/scripts/setupCluster.js
MYSQL_SCRIPT=/scripts/db.sql/scripts/db.sql 는 어플리케이션 서버에서 사용할 DB와 유저를 만드는 SQL 이고,
CREATE DATABASE dbwebappdb; CREATE USER 'dbwebapp'@'%' IDENTIFIED BY 'dbwebapp'; GRANT ALL PRIVILEGES ON dbwebappdb.* TO 'dbwebapp'@'%';
/scripts/setupCluster.js 가 바로 클러스터 구성을 시작하는 명령이다.
var dbPass = "mysql" var clusterName = "devCluster" try { print('Setting up InnoDB cluster...\n'); shell.connect('root@mysql-server-1:3306', dbPass) var cluster = dba.createCluster(clusterName); print('Adding instances to the cluster.'); cluster.addInstance({user: "root", host: "mysql-server-2", password: dbPass}) print('.'); cluster.addInstance({user: "root", host: "mysql-server-3", password: dbPass}) print('.\nInstances successfully added to the cluster.'); print('\nInnoDB cluster deployed successfully.\n'); } catch(e) { print('\nThe InnoDB cluster could not be created.\n\nError: ' + e.message + '\n'); }
mysql-shell 에서는 이 JS 코드로 작성된 명령어를 실행해 클러스터 환경을 구축하게 되는데 각 과정을 살펴보면 다음과 같다.
1. 프라이머리로 사용할 서버에 접속하기
var dbPass = "mysql" shell.connect('root@mysql-server-1:3306', dbPass)
2. createCluster 명령으로 클러스터링 시작하기
var clusterName = "devCluster" var cluster = dba.createCluster(clusterName);
실제로 InnoDB 클러스터를 구축하려면 MySQL 서버에 그룹 복제를 설정하는 등의 복잡한 작업이 필요한데 이러한 작업을 dba.createCluster() 메서드에서 모두 자동으로 처리해 준다.
- 클러스터 정보 저장할 메타데이터들 생성 및 설정
- 그룹복제 설정 및 시작
- 그룹복제 분산 복구에서 사용될 DB 계성 생성
InnoDB 클러스터는 기본적으로 싱글 프라이머리 모드로 생성되며 처음 클러스터 생성을 진행한 MySQL 서버가 프라이머리로 지정된다. mysql-server-1에 접속해 createCluster 명령을 수행했으므로 mysql-server-1이 프라이머리 서버가 된다.
3. lnnoDB 클러스터 인스턴스 추가
var dbPass = "mysql" cluster.addInstance({user: "root", host: "mysql-server-2", password: dbPass}) cluster.addInstance({user: "root", host: "mysql-server-3", password: dbPass})
addInstance() 메서드로 mysql-server-2 와 mysql-server-3을 클러스터의 멤버, 세컨더리 서버로 등록해준다.
클러스터에 이미 프라이머리 서버(mysql-server-1)가 존재하므로 이후 클러스터에 추가되는 서버(mysql-server-2, mysql-server-3)들은 모두 자동으로 읽기 전용으로 설정된다.
docker-compose-innodb-cluster-mysql-shell-1 | The instance 'root@mysql-server-2' was successfully added to the cluster. docker-compose-innodb-cluster-mysql-shell-1 | docker-compose-innodb-cluster-mysql-shell-1 | .A new instance will be added to the InnoDB cluster. Depending on the amount of docker-compose-innodb-cluster-mysql-shell-1 | data on the cluster this might take from a few seconds to several hours. docker-compose-innodb-cluster-mysql-shell-1 | docker-compose-innodb-cluster-mysql-shell-1 | Adding instance to the cluster ... docker-compose-innodb-cluster-mysql-shell-1 | docker-compose-innodb-cluster-mysql-router-1 | 2023-07-02 07:31:18 metadata_cache INFO [40b0ba3700] Potential changes detected in cluster after metadata refresh (view_id=0) docker-compose-innodb-cluster-mysql-router-1 | 2023-07-02 07:31:18 metadata_cache INFO [40b0ba3700] Metadata for cluster 'devCluster' has 2 member(s), single-primary: docker-compose-innodb-cluster-mysql-router-1 | 2023-07-02 07:31:18 metadata_cache INFO [40b0ba3700] mysql-server-1:3306 / 33060 - mode=RW docker-compose-innodb-cluster-mysql-router-1 | 2023-07-02 07:31:18 metadata_cache INFO [40b0ba3700] mysql-server-2:3306 / 33060 - mode=n/a docker-compose-innodb-cluster-mysql-shell-1 | Validating instance at mysql-server-3:3306... docker-compose-innodb-cluster-mysql-shell-1 | docker-compose-innodb-cluster-mysql-shell-1 | This instance reports its own address as eac19e522bcc docker-compose-innodb-cluster-mysql-server-2-1 | 2023-07-02T07:31:19.405408Z 19 [System] [MY-010597] [Repl] 'CHANGE MASTER TO FOR CHANNEL 'group_replication_recovery' executed'. Previous state master_host='1dc2b8a7be4a', master_port= 3306, master_log_file='', master_log_pos= 4, master_bind=''. New state master_host='<NULL>', master_port= 0, master_log_file='', master_log_pos= 4, master_bind=''. docker-compose-innodb-cluster-mysql-router-1 | 2023-07-02 07:31:20 metadata_cache INFO [40b0ba3700] Potential changes detected in cluster after metadata refresh (view_id=0) docker-compose-innodb-cluster-mysql-router-1 | 2023-07-02 07:31:20 metadata_cache INFO [40b0ba3700] Metadata for cluster 'devCluster' has 2 member(s), single-primary: docker-compose-innodb-cluster-mysql-router-1 | 2023-07-02 07:31:20 metadata_cache INFO [40b0ba3700] mysql-server-1:3306 / 33060 - mode=RW docker-compose-innodb-cluster-mysql-router-1 | 2023-07-02 07:31:20 metadata_cache INFO [40b0ba3700] mysql-server-2:3306 / 33060 - mode=RO docker-compose-innodb-cluster-mysql-shell-1 | docker-compose-innodb-cluster-mysql-shell-1 | Instance configuration is suitable.
.addInstance() 메서드가 실행된 후 로그를 살펴보면
처음에 mysql-server-2가 클러스터에 추가되면 메타데이터 캐시 로그에 mode=n/a 로 보여지는데 이는 아직 해당 인스턴스가 아직 그룹 복제에 참여하고 있지 않음을 나타낸다.
mysql-server-1:3306 / 33060 - mode=RW
mysql-server-2:3306 / 33060 - mode=n/a이후 로그를 살펴보면 mode=RO 로 읽기 전용으로 설정 된것을 확인 할 수 있다.
mysql-server-1:3306 / 33060 - mode=RW
mysql-server-2:3306 / 33060 - mode=ROMySQL-Router 에서 하는 일 살펴보기
어플리케이션 서버 연결은 이제 각 DB 인스턴스가 아니라 MySQL-Router 에 연결한다.
docker-compose.yml 파일과 dbwebapp.env파일을 보면 예시 어플리케이션 서버인 dbwebapp가 어떻게 DB 와 커넥션을 맺고있는지 확인 할 수 있는데,
docker-compose.yml dbwebapp: platform: linux/x86_64 env_file: - dbwebapp.env image: neumayer/dbwebapp ports: - "8080:8080" depends_on: - mysql-router
dbwebapp.env DBUSER=dbwebapp DBPASS=dbwebapp DBNAME=dbwebappdb DBHOST=mysql-router DBPORT=6446
어플리케이션 서버는 각 인스턴스에 바로 연결 하는된것이 아니라 mysql-router에 연결되어있는 것을 확인 할 수 있다.
mysql-router는 어플리케이션 서버에 연결되어 쿼리 부하를 분산해주고 각 DB 인스턴스들의 클러스터 구성이 변경되었는지 자동으로 확인하며, 만약 문제가 생겼을경우 자동 페일오버를 수행한다.
그렇기 때문에 어플리케이션 서버단에서는 MySQL 서버에 문제가 생기더라도 별도의 조치없이 정상적으로 쿼리를 실행 할수 있게된다.
프라이머리 서버 강제 종료 시켜보기 테스트
docker ps 로 프라이머리 서버 컨테이너를 강제 종료 시켜보았다.
docker-compose 로그를 통해 어떤일이 일어나는 지 확인을 해보았다.
docker-compose-innodb-cluster-mysql-router-1 | 2023-07-02 15:09:46 metadata_cache WARNING [40b0ba3700] Failed connecting with Metadata Server mysql-server-1:3306: Lost connection to MySQL server at 'reading initial communication packet', system error: 104 (2013) docker-compose-innodb-cluster-mysql-router-1 | 2023-07-02 15:09:47 metadata_cache INFO [40b0ba3700] Connected with metadata server running on mysql-server-2:3306 docker-compose-innodb-cluster-mysql-router-1 | 2023-07-02 15:09:47 metadata_cache WARNING [40b0ba3700] While updating metadata, could not establish a connection to cluster 'devCluster' through mysql-server-1:3306 docker-compose-innodb-cluster-mysql-router-1 | 2023-07-02 15:09:48 metadata_cache WARNING [40b0ba3700] Failed connecting with Metadata Server mysql-server-1:3306: Can't connect to MySQL server on 'mysql-server-1:3306' (111) (2003) docker-compose-innodb-cluster-mysql-router-1 | 2023-07-02 15:09:48 routing INFO [4004a48700] Stop accepting connections for routing routing:bootstrap_rw listening on 6446 docker-compose-innodb-cluster-mysql-server-1-1 | 2023-07-02T15:09:48.980603Z 0 [Warning] [MY-010909] [Server] /usr/sbin/mysqld: Forcing close of thread 38857 user: 'dbwebapp'. docker-compose-innodb-cluster-mysql-server-1-1 | 2023-07-02T15:09:48.981206Z 0 [Warning] [MY-010909] [Server] /usr/sbin/mysqld: Forcing close of thread 99 user: 'dbwebapp'. docker-compose-innodb-cluster-mysql-server-1-1 | 2023-07-02T15:09:48.985611Z 0 [Warning] [MY-010909] [Server] /usr/sbin/mysqld: Forcing close of thread 9085 user: 'dbwebapp'. docker-compose-innodb-cluster-mysql-server-1-1 | 2023-07-02T15:09:48.985786Z 0 [Warning] [MY-010909] [Server] /usr/sbin/mysqld: Forcing close of thread 5926 user: 'dbwebapp'. docker-compose-innodb-cluster-mysql-server-1-1 | 2023-07-02T15:09:48.985858Z 0 [Warning] [MY-010909] [Server] /usr/sbin/mysqld: Forcing close of thread 38855 user: 'dbwebapp'. docker-compose-innodb-cluster-mysql-server-1-1 | 2023-07-02T15:09:48.985984Z 0 [Warning] [MY-010909] [Server] /usr/sbin/mysqld: Forcing close of thread 9087 user: 'dbwebapp'. docker-compose-innodb-cluster-mysql-server-1-1 | 2023-07-02T15:09:48.995874Z 0 [Warning] [MY-010909] [Server] /usr/sbin/mysqld: Forcing close of thread 6671 user: 'root'. docker-compose-innodb-cluster-mysql-server-2-1 | 2023-07-02T15:09:51.194827Z 0 [Warning] [MY-011499] [Repl] Plugin group_replication reported: 'Members removed from the group: 1dc2b8a7be4a:3306' docker-compose-innodb-cluster-mysql-server-3-1 | 2023-07-02T15:09:51.195953Z 0 [Warning] [MY-011499] [Repl] Plugin group_replication reported: 'Members removed from the group: 1dc2b8a7be4a:3306' docker-compose-innodb-cluster-mysql-router-1 | 2023-07-02 15:09:51 metadata_cache WARNING [40b0ba3700] Member mysql-server-1:3306 (4a32401b-18aa-11ee-a01c-0242c0a8e004) defined in metadata not found in actual Group Replication docker-compose-innodb-cluster-mysql-router-1 | 2023-07-02 15:09:51 metadata_cache INFO [40b0ba3700] Potential changes detected in cluster after metadata refresh (view_id=0) docker-compose-innodb-cluster-mysql-router-1 | 2023-07-02 15:09:51 metadata_cache INFO [40b0ba3700] Metadata for cluster 'devCluster' has 3 member(s), single-primary: docker-compose-innodb-cluster-mysql-router-1 | 2023-07-02 15:09:51 metadata_cache INFO [40b0ba3700] mysql-server-1:3306 / 33060 - mode=n/a docker-compose-innodb-cluster-mysql-router-1 | 2023-07-02 15:09:51 metadata_cache INFO [40b0ba3700] mysql-server-2:3306 / 33060 - mode=RW docker-compose-innodb-cluster-mysql-router-1 | 2023-07-02 15:09:51 metadata_cache INFO [40b0ba3700] mysql-server-3:3306 / 33060 - mode=RO docker-compose-innodb-cluster-mysql-router-1 | 2023-07-02 15:09:51 routing INFO [40b0ba3700] Disconnecting client 127.0.0.1:46658 from server 192.168.224.4:3306 docker-compose-innodb-cluster-mysql-router-1 | 2023-07-02 15:09:51 routing INFO [40b0ba3700] Routing routing:bootstrap_rw listening on 6446 got request to disconnect 1 invalid connections: metadata change docker-compose-innodb-cluster-mysql-router-1 | 2023-07-02 15:09:51 routing INFO [40b0ba3700] Start accepting connections for routing routing:bootstrap_rw listening on 6446 docker-compose-innodb-cluster-mysql-server-1-1 | 2023-07-02T15:09:53.789387Z 30 [ERROR] [MY-011735] [Repl] Plugin group_replication reported: '[GCS] Error pushing message into group communication engine.' docker-compose-innodb-cluster-mysql-server-1-1 | 2023-07-02T15:09:54.792949Z 30 [ERROR] [MY-011735] [Repl] Plugin group_replication reported: '[GCS] Error pushing message into group communication engine.' docker-compose-innodb-cluster-mysql-server-1-1 | 2023-07-02T15:09:55.793411Z 30 [ERROR] [MY-011735] [Repl] Plugin group_replication reported: '[GCS] Error pushing message into group communication engine.' docker-compose-innodb-cluster-mysql-router-1 | 2023-07-02 15:10:04 metadata_cache WARNING [40b0ba3700] Failed connecting with Metadata Server mysql-server-1:3306: Unknown MySQL server host 'mysql-server-1' (-2) (2005) docker-compose-innodb-cluster-mysql-server-1-1 exited with code 137 docker-compose-innodb-cluster-mysql-server-1-1 exited with code 0
mysql-router 에서 찍힌 로그만 살펴보면, mysql-server-1 에 연결할 수 없다는 것을 알게 되고 나서
mysql-server-1:3306 / 33060 - mode=n/a
mysql-server-2:3306 / 33060 - mode=RW
mysql-server-3:3306 / 33060 - mode=ROmysql-server-2 가 mode=RW로 설정되어 읽기, 쓰기 작업이 가능한 마스터 서버로 격상된 것을 확인 할 수 있었다.
그룹 복제 테스트
dbwebapp.env 에 기입된 정보로 연결하여 테이블을 만들고 데이터를 추가했을때 다른 그룹 멤버들에게도 변경사항이 잘 반영되는지 확인해보았다.
dbwebapp.env DBUSER=dbwebapp DBPASS=dbwebapp DBNAME=dbwebappdb DBHOST=mysql-router DBPORT=6446
create table test ( name varchar(30), age int ); insert into test (name, age) values ("han", 12);
문제상황
테스트 테이블을 만든 후 INSERT INTO로 데이터를 추가했는데 다음과 같은 오류가 발생했다...
The table does not comply with the requirements by an external plugin.
그리고 docker-compose 로그를 확인해보니
docker-compose-innodb-cluster-mysql-server-1-1 | 2023-07-02T14:31:47.099932Z 38855 [ERROR] [MY-011542] [Repl] Plugin group_replication reported: 'Table test does not have any PRIMARY KEY. This is not compatible with Group Replication.'
'Table test does not have any PRIMARY KEY. This is not compatible with Group Replication.'
INSERT INTO 작업은 쓰기 작업이기 때문에 프라이머리 서버인 mysql-server-1에서 에러로그가 발생 되었고, 발생된 로그를 확인 해보니 PRIMARY KEY가 없다! 라는 에러가 나왔다.
원인
https://dev.mysql.com/doc/refman/8.0/en/group-replication-requirements.html
위 group replication requirement 문서에 나온 내용중 놓친 부분이 있었는데, 그룹 복제에 참여하는 테이블은 모두 명시적으로 프라이머리 키를 가지고 있어야 한다고 한다.(명시적으로 지정하지 않을 경우에는 NOT NULL 속성의 유니크 키라도 있어야 한다.)
그룹 복제에서는 이 키들이 테이블 내 모든 데이터에 대해 고유한 식별자 역할을 하고 이 식별자로 트랜잭션간 충돌을 감지한다고 한다.
해결
pk를 지정해 주니까 제대로 INSERT INTO 문장이 실행되었고, 다른 읽기 전용 세컨더리 서버에서도 그 결과를 확인 할 수 있었다.
'✏️ 스터디 모음집 > RealMySQL 스터디' 카테고리의 다른 글
Real MySQL 8.0 - 9.3 인덱스 컨디션 푸쉬다운 (0) 2023.05.21 Real MySQL 8.0 - 9.3 고급 최적화 - MySQL의 조인 방식들 (0) 2023.03.26 Real MySQL 8.0 8장 - 인덱스는 왼쪽이 중요하다. (0) 2023.03.26 Real MySQL 8.0 8장 - 인덱스 정렬 및 스캔의 방향 (0) 2023.03.26 Real MySQL 8.0 7장 - MySQL 암호화 (0) 2023.02.26