diff --git a/ansible/mysql-deploy-callback.yml b/ansible/mysql-deploy-callback.yml index 01d2526..ae46d03 100644 --- a/ansible/mysql-deploy-callback.yml +++ b/ansible/mysql-deploy-callback.yml @@ -452,15 +452,27 @@ EOF if ! /usr/bin/mysql --defaults-extra-file="$client_file" -e 'SELECT 1' >/dev/null 2>&1; then 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("'", "''") }}'; EOF /usr/bin/mysql --protocol=socket --socket={{ mysql_run_dir }}/mysql.sock -uroot <"$sql_file" fi 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("'", "''") }}'; ALTER USER 'root'@'%' IDENTIFIED BY '{{ mysql_root_password_value | replace("'", "''") }}'; GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION; 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 /usr/bin/mysql --defaults-extra-file="$client_file" <"$sql_file" executable: /bin/bash diff --git a/ansible/mysql-deploy.yml b/ansible/mysql-deploy.yml index 143c5f1..d59a54b 100644 --- a/ansible/mysql-deploy.yml +++ b/ansible/mysql-deploy.yml @@ -355,15 +355,27 @@ EOF if ! /usr/bin/mysql --defaults-extra-file="$client_file" -e 'SELECT 1' >/dev/null 2>&1; then 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("'", "''") }}'; EOF /usr/bin/mysql --protocol=socket --socket={{ mysql_run_dir }}/mysql.sock -uroot <"$sql_file" fi 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("'", "''") }}'; ALTER USER 'root'@'%' IDENTIFIED BY '{{ mysql_root_password_value | replace("'", "''") }}'; GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION; 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 /usr/bin/mysql --defaults-extra-file="$client_file" <"$sql_file" executable: /bin/bash diff --git a/ansible/templates/mysql-instance.cnf.j2 b/ansible/templates/mysql-instance.cnf.j2 index fc3918c..fffb5be 100644 --- a/ansible/templates/mysql-instance.cnf.j2 +++ b/ansible/templates/mysql-instance.cnf.j2 @@ -53,6 +53,12 @@ binlog-expire-logs-seconds={{ mysql_binlog_expire_logs_seconds }} # binlog 过 gtid-mode=ON # 启用 GTID(全局事务标识符) enforce-gtid-consistency=ON # 强制 GTID 一致性(确保复制安全) 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 %} # =============================================================================