fix(ansible): 一主多从从库强制只读
- mysql-instance.cnf.j2 按 mysql_node_role=replica 注入 read-only/super-read-only, 阻止业务直接写入从库导致主从数据分叉(复制线程与复制管理语句不受影响) - 账号配置任务在从库上临时放开只读、配置完成后回锁, 避免 cnf 只读拒绝 ALTER/CREATE USER;主库与 standalone 不受影响
This commit is contained in:
@@ -452,15 +452,27 @@
|
|||||||
EOF
|
EOF
|
||||||
if ! /usr/bin/mysql --defaults-extra-file="$client_file" -e 'SELECT 1' >/dev/null 2>&1; then
|
if ! /usr/bin/mysql --defaults-extra-file="$client_file" -e 'SELECT 1' >/dev/null 2>&1; then
|
||||||
cat >"$sql_file" <<'EOF'
|
cat >"$sql_file" <<'EOF'
|
||||||
|
{% if topology == 'primary_replica' and inventory_hostname != mysql_primary_host_value %}
|
||||||
|
SET GLOBAL super_read_only = OFF;
|
||||||
|
SET GLOBAL read_only = OFF;
|
||||||
|
{% endif %}
|
||||||
ALTER USER 'root'@'localhost' IDENTIFIED BY '{{ mysql_root_password_value | replace("'", "''") }}';
|
ALTER USER 'root'@'localhost' IDENTIFIED BY '{{ mysql_root_password_value | replace("'", "''") }}';
|
||||||
EOF
|
EOF
|
||||||
/usr/bin/mysql --protocol=socket --socket={{ mysql_run_dir }}/mysql.sock -uroot <"$sql_file"
|
/usr/bin/mysql --protocol=socket --socket={{ mysql_run_dir }}/mysql.sock -uroot <"$sql_file"
|
||||||
fi
|
fi
|
||||||
cat >"$sql_file" <<'EOF'
|
cat >"$sql_file" <<'EOF'
|
||||||
|
{% if topology == 'primary_replica' and inventory_hostname != mysql_primary_host_value %}
|
||||||
|
SET GLOBAL super_read_only = OFF;
|
||||||
|
SET GLOBAL read_only = OFF;
|
||||||
|
{% endif %}
|
||||||
CREATE USER IF NOT EXISTS 'root'@'%' IDENTIFIED BY '{{ mysql_root_password_value | replace("'", "''") }}';
|
CREATE USER IF NOT EXISTS 'root'@'%' IDENTIFIED BY '{{ mysql_root_password_value | replace("'", "''") }}';
|
||||||
ALTER USER 'root'@'%' IDENTIFIED BY '{{ mysql_root_password_value | replace("'", "''") }}';
|
ALTER USER 'root'@'%' IDENTIFIED BY '{{ mysql_root_password_value | replace("'", "''") }}';
|
||||||
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
|
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
|
||||||
FLUSH PRIVILEGES;
|
FLUSH PRIVILEGES;
|
||||||
|
{% if topology == 'primary_replica' and inventory_hostname != mysql_primary_host_value %}
|
||||||
|
SET GLOBAL read_only = ON;
|
||||||
|
SET GLOBAL super_read_only = ON;
|
||||||
|
{% endif %}
|
||||||
EOF
|
EOF
|
||||||
/usr/bin/mysql --defaults-extra-file="$client_file" <"$sql_file"
|
/usr/bin/mysql --defaults-extra-file="$client_file" <"$sql_file"
|
||||||
executable: /bin/bash
|
executable: /bin/bash
|
||||||
|
|||||||
@@ -355,15 +355,27 @@
|
|||||||
EOF
|
EOF
|
||||||
if ! /usr/bin/mysql --defaults-extra-file="$client_file" -e 'SELECT 1' >/dev/null 2>&1; then
|
if ! /usr/bin/mysql --defaults-extra-file="$client_file" -e 'SELECT 1' >/dev/null 2>&1; then
|
||||||
cat >"$sql_file" <<'EOF'
|
cat >"$sql_file" <<'EOF'
|
||||||
|
{% if topology == 'primary_replica' and inventory_hostname != mysql_primary_host_value %}
|
||||||
|
SET GLOBAL super_read_only = OFF;
|
||||||
|
SET GLOBAL read_only = OFF;
|
||||||
|
{% endif %}
|
||||||
ALTER USER 'root'@'localhost' IDENTIFIED BY '{{ mysql_root_password_value | replace("'", "''") }}';
|
ALTER USER 'root'@'localhost' IDENTIFIED BY '{{ mysql_root_password_value | replace("'", "''") }}';
|
||||||
EOF
|
EOF
|
||||||
/usr/bin/mysql --protocol=socket --socket={{ mysql_run_dir }}/mysql.sock -uroot <"$sql_file"
|
/usr/bin/mysql --protocol=socket --socket={{ mysql_run_dir }}/mysql.sock -uroot <"$sql_file"
|
||||||
fi
|
fi
|
||||||
cat >"$sql_file" <<'EOF'
|
cat >"$sql_file" <<'EOF'
|
||||||
|
{% if topology == 'primary_replica' and inventory_hostname != mysql_primary_host_value %}
|
||||||
|
SET GLOBAL super_read_only = OFF;
|
||||||
|
SET GLOBAL read_only = OFF;
|
||||||
|
{% endif %}
|
||||||
CREATE USER IF NOT EXISTS 'root'@'%' IDENTIFIED BY '{{ mysql_root_password_value | replace("'", "''") }}';
|
CREATE USER IF NOT EXISTS 'root'@'%' IDENTIFIED BY '{{ mysql_root_password_value | replace("'", "''") }}';
|
||||||
ALTER USER 'root'@'%' IDENTIFIED BY '{{ mysql_root_password_value | replace("'", "''") }}';
|
ALTER USER 'root'@'%' IDENTIFIED BY '{{ mysql_root_password_value | replace("'", "''") }}';
|
||||||
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
|
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
|
||||||
FLUSH PRIVILEGES;
|
FLUSH PRIVILEGES;
|
||||||
|
{% if topology == 'primary_replica' and inventory_hostname != mysql_primary_host_value %}
|
||||||
|
SET GLOBAL read_only = ON;
|
||||||
|
SET GLOBAL super_read_only = ON;
|
||||||
|
{% endif %}
|
||||||
EOF
|
EOF
|
||||||
/usr/bin/mysql --defaults-extra-file="$client_file" <"$sql_file"
|
/usr/bin/mysql --defaults-extra-file="$client_file" <"$sql_file"
|
||||||
executable: /bin/bash
|
executable: /bin/bash
|
||||||
|
|||||||
@@ -53,6 +53,12 @@ binlog-expire-logs-seconds={{ mysql_binlog_expire_logs_seconds }} # binlog 过
|
|||||||
gtid-mode=ON # 启用 GTID(全局事务标识符)
|
gtid-mode=ON # 启用 GTID(全局事务标识符)
|
||||||
enforce-gtid-consistency=ON # 强制 GTID 一致性(确保复制安全)
|
enforce-gtid-consistency=ON # 强制 GTID 一致性(确保复制安全)
|
||||||
relay-log={{ mysql_binlog_dir }}/relay-bin # 中继日志路径(从库重放 binlog 使用)
|
relay-log={{ mysql_binlog_dir }}/relay-bin # 中继日志路径(从库重放 binlog 使用)
|
||||||
|
{% if mysql_node_role | default('') == 'replica' %}
|
||||||
|
# 从库强制只读:阻止业务直接写入从库导致主从数据分叉
|
||||||
|
# 复制线程与 CHANGE REPLICATION SOURCE 等复制管理语句不受影响
|
||||||
|
read-only=ON
|
||||||
|
super-read-only=ON
|
||||||
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
|||||||
Reference in New Issue
Block a user