Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
5556aa1
PMM-13992: New Percona Server for MySQL setup with cgroups support.
peterSirotnak Nov 24, 2025
4a5dd66
PMM-13992: Test data
peterSirotnak Nov 24, 2025
09cfb44
PMM-13992: Test data
peterSirotnak Nov 24, 2025
8704573
PMM-13992: Add support for mysql
peterSirotnak Nov 24, 2025
29ca32a
PMM-13992: Remove old Percona server setup
peterSirotnak Nov 24, 2025
a354cc6
PMM-13992: Fix mysql setup for 5.7
peterSirotnak Nov 24, 2025
5f692b2
PMM-13992: Fix mysql setup gr for 8.4
peterSirotnak Nov 24, 2025
c4a366a
PMM-13992: Fix naming
peterSirotnak Nov 24, 2025
fcf8cdc
PMM-13992: Add innodb compression to mysql
peterSirotnak Nov 24, 2025
3eb04b2
PMM-13992: Bigger test data
peterSirotnak Nov 24, 2025
7f5def6
PMM-13992: Bigger test data
peterSirotnak Nov 24, 2025
cfc8a9e
PMM-13992: Bigger test data
peterSirotnak Nov 24, 2025
cdba5b7
PMM-13992: Bigger test data
peterSirotnak Nov 24, 2025
c3d3c6e
PMM-13992: Bigger test data
peterSirotnak Nov 24, 2025
3a4b6ea
PMM-13992: Bigger test data
peterSirotnak Nov 24, 2025
349ea57
PMM-13992: Bigger test data
peterSirotnak Nov 24, 2025
b6c0809
PMM-13992: Bigger test data
peterSirotnak Nov 24, 2025
221e429
PMM-13992: Bigger test data
peterSirotnak Nov 24, 2025
707deaa
PMM-13992: Bigger test data
peterSirotnak Nov 24, 2025
0927397
PMM-13992: Bigger test data
peterSirotnak Nov 24, 2025
d4c8c53
PMM-13992: Bigger test data
peterSirotnak Nov 24, 2025
0d1ee57
PMM-13992: Bigger test data
peterSirotnak Nov 24, 2025
1534d90
PMM-13992: Bigger test data
peterSirotnak Nov 24, 2025
82925c5
PMM-13992: Bigger test data
peterSirotnak Nov 24, 2025
06f9990
PMM-13992: Bigger test data
peterSirotnak Nov 24, 2025
377a6d1
PMM-13992: Bigger test data
peterSirotnak Nov 24, 2025
e04b865
PMM-13992: Bigger test data
peterSirotnak Nov 24, 2025
97e7c6c
PMM-13992: Bigger test data
peterSirotnak Nov 24, 2025
fb2d108
PMM-13992: Bigger test data
peterSirotnak Nov 24, 2025
5612bbb
PMM-13992: Bigger test data
peterSirotnak Nov 25, 2025
e3e9724
PMM-13992: Bigger test data
peterSirotnak Nov 25, 2025
d6f4e6e
PMM-13992: Bigger test data
peterSirotnak Nov 25, 2025
ad927b3
PMM-13992: Bigger test data
peterSirotnak Nov 25, 2025
cd47227
PMM-13992: Bigger test data
peterSirotnak Nov 25, 2025
53197e5
PMM-13992: Bigger test data
peterSirotnak Nov 25, 2025
79d7a77
PMM-13992: Bigger test data
peterSirotnak Nov 25, 2025
73aa4c1
PMM-13992: Bigger test data
peterSirotnak Nov 25, 2025
de1b240
PMM-13992: add mysqldump to path
peterSirotnak Nov 25, 2025
a39402e
PMM-13992: Remove data generation
peterSirotnak Nov 26, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ CREATE TABLE students (
first_name VARCHAR(50),
last_name VARCHAR(50),
birth_date DATE
);
) ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8;

CREATE TABLE classes (
class_id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100),
teacher VARCHAR(100)
);
) ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8;

CREATE TABLE enrollments (
enrollment_id INT AUTO_INCREMENT PRIMARY KEY,
Expand All @@ -22,7 +22,7 @@ CREATE TABLE enrollments (
enrollment_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (student_id) REFERENCES students(student_id),
FOREIGN KEY (class_id) REFERENCES classes(class_id)
);
) ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8;

-- ========================================
-- INSERT INITIAL DATA
Expand Down Expand Up @@ -91,4 +91,4 @@ DELETE FROM enrollments
WHERE student_id = (SELECT student_id FROM students WHERE first_name = 'Alice' AND last_name = 'Smith');

DELETE FROM students
WHERE first_name = 'Alice' AND last_name = 'Smith';
WHERE first_name = 'Alice' AND last_name = 'Smith';
37 changes: 37 additions & 0 deletions pmm_qa/mysql/data/my-async-replication-57.cnf.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
[mysqld]
# General server configuration
server_id={{ item }}
bind-address=0.0.0.0
port={{ mysql_listen_port }}

# Replication settings
gtid_mode=ON
enforce_gtid_consistency=ON
log_bin=binlog
log_slave_updates=ON
sync_binlog=1
binlog_checksum=NONE
# Only disable engines supported in 5.7 and safe for GTID
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE"
# MacOS-specific, where table names are case-sensitive
lower_case_table_names=2

# Optional: report_host is valid in 5.7
report_host={{ container_prefix }}{{ item }}

# Replica configuration - applies to all nodes except primary (they'll be able to become replicas)
{% if item != 1 %}
# Replica specific settings (use slave_parallel_* in 5.7)
slave_parallel_workers=4
slave_parallel_type=LOGICAL_CLOCK
slave_preserve_commit_order=1
{% endif %}

# Crash-safe replication settings
relay-log={{ container_prefix }}{{ item }}-relay-bin
relay_log_recovery=ON
relay_log_purge=ON

# Performance and connection settings
max_connections=1000
innodb_buffer_pool_size=256M
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
server_id={{ item }}
bind-address=0.0.0.0
port={{ mysql_listen_port }}
userstat=1

# Authentication settings for caching_sha2_password
caching_sha2_password_auto_generate_rsa_keys=ON
Expand All @@ -23,7 +22,7 @@ disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
lower_case_table_names=2

# MySQL 8.4 compatibility settings
report_host=ps_pmm_{{ ps_version }}_{{ item }}
report_host={{ container_prefix }}{{ item }}

# Replica configuration - applies to all nodes except primary (they'll be able to become replicas)
{% if item != 1 %}
Expand All @@ -34,7 +33,7 @@ replica_preserve_commit_order=1
{% endif %}

# Crash-safe replication settings
relay-log=ps_pmm_{{ ps_version }}_{{ item }}-relay-bin
relay-log={{ container_prefix }}{{ item }}-relay-bin
relay_log_recovery=ON
relay_log_purge=ON

Expand Down
48 changes: 48 additions & 0 deletions pmm_qa/mysql/data/my-group-replication-57.cnf.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
[mysqld]
# General server configuration
server_id={{ server_id_start + item - 1 }}
binlog_format=ROW
bind-address=0.0.0.0
port={{ mysql_listen_port }}

# 5.7 General replication settings
gtid_mode=ON
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
transaction_write_set_extraction=XXHASH64
binlog_checksum=NONE
log_bin=binlog
log_slave_updates=ON
# NO: disabled_storage_engines in 5.7
lower_case_table_names=2

# Report host for replication/monitoring
report_host={{ container_prefix }}{{ item }}

# Group Replication Settings
# (Available in MySQL 5.7.17+ and must be installed as plugin)
plugin_load_add='group_replication.so'
loose-group_replication_group_name='aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'
loose-group_replication_local_address='{{ container_prefix }}{{ item }}:{{ group_seeds_port }}'
loose-group_replication_group_seeds={% for i in range(1, nodes_count | int + 1) %}{{ container_prefix }}{{ i }}:{{ group_seeds_port }}{% if not loop.last %},{% endif %}{% endfor %}
loose-group_replication_communication_stack=XCOM

# Group replication behavior
loose-group_replication_start_on_boot=OFF
loose-group_replication_bootstrap_group=OFF
loose-group_replication_single_primary_mode=ON
loose-group_replication_enforce_update_everywhere_checks=OFF

# Recovery settings
loose-group_replication_recovery_retry_count=10
loose-group_replication_recovery_reconnect_interval=60

# Crash-safe replication settings
relay-log={{ container_prefix }}{{ item }}-relay-bin
relay_log_recovery=ON
relay_log_purge=ON

# Performance and connection settings
max_connections=1000
innodb_buffer_pool_size=256M
44 changes: 44 additions & 0 deletions pmm_qa/mysql/data/my-group-replication.cnf.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
[mysqld]
# General server configuration
server_id={{ server_id_start + item - 1 }}
bind-address=0.0.0.0
port={{ mysql_listen_port }}

# General replication settings
gtid_mode=ON
enforce_gtid_consistency=ON
binlog_checksum=NONE
log_bin=binlog
log_replica_updates=ON
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
lower_case_table_names=2 # MacOS-specific, but also good generally

# MySQL 8.4 compatibility settings
report_host={{ container_prefix }}{{ item }}

# Group Replication Settings
plugin_load_add='group_replication.so'
loose-group_replication_group_name='aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'
loose-group_replication_local_address='{{ container_prefix }}{{ item }}:{{ group_seeds_port }}'
loose-group_replication_group_seeds='{% for i in range(1, nodes_count | int + 1) %}{{ container_prefix }}{{ i }}:{{ group_seeds_port }}{% if not loop.last %},{% endif %}{% endfor %}'
loose-group_replication_communication_stack=XCOM

# Group replication behavior
loose-group_replication_start_on_boot=OFF
loose-group_replication_bootstrap_group=OFF
loose-group_replication_single_primary_mode=ON
loose-group_replication_enforce_update_everywhere_checks=OFF

# Recovery settings
loose-group_replication_recovery_get_public_key=ON
loose-group_replication_recovery_retry_count=10
loose-group_replication_recovery_reconnect_interval=60

# Crash-safe replication settings
relay-log={{ container_prefix }}{{ item }}-relay-bin
relay_log_recovery=ON
relay_log_purge=ON

# Performance and connection settings
max_connections=1000
innodb_buffer_pool_size=256M
2 changes: 2 additions & 0 deletions pmm_qa/mysql/data/my.cnf.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[mysqld]
plugin-load-add=auth_native_password.so
173 changes: 173 additions & 0 deletions pmm_qa/mysql/mysql-setup.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
---

- name: MySQL single, cluster with group Replication in Docker
hosts: localhost
connection: local
gather_facts: yes
vars:
mysql_version: "{{ (lookup('env', 'MS_VERSION') | default('8.0', true)) | replace('.', '_') }}"
replication_user: "repl_user"
replication_password: "GRgrO9301RuF"
root_password: "GRgrO9301RuF"
mysql_port: 33066
mysql_listen_port: 3306
group_seeds_port: 34061
nodes_count: "{{ (lookup('env', 'NODES_COUNT') | default('1', true)) | int }}"
network_name: "pmm-qa"
data_dir: "{{ lookup('env', 'HOME') }}/mysql_cluster_data"
server_id_start: 1
pmm_server_ip: "{{ lookup('vars', 'extra_pmm_server_ip', default=lookup('env','PMM_SERVER_IP') | default('127.0.0.1', true) ) }}"
client_version: "{{ lookup('vars', 'extra_client_version', default=lookup('env','CLIENT_VERSION') | default('3-dev-latest', true) ) }}"
admin_password: "{{ lookup('vars', 'extra_admin_password', default=lookup('env','ADMIN_PASSWORD') | default('admin', true) ) }}"
query_source: "{{ lookup('env', 'QUERY_SOURCE') | default('perfschema', true) }}"
metrics_mode: "{{ lookup('env', 'metrics_mode') }}"
setup_type: "{{ lookup('env', 'SETUP_TYPE') }}"
random_service_name_value: ""
my_rocks: "{{ lookup('env', 'MY_ROCKS') | default(false, true) }}"
container_prefix: "mysql_pmm{{ (setup_type|default('')) and '_' ~ setup_type }}_{{ mysql_version }}_"

tasks:
# - name: Fail if setup_type is gr or replication and version is less than 80
# fail:
# msg: "This setup_type ({{ setup_type }}) with version {{ mysql_version | replace('_', '.') }} is not supported!"
# when: (setup_type == 'gr' or setup_type == 'replication') and (mysql_version | replace('_', '') | int < 80)

- name: Modify the node count for group replication
set_fact:
nodes_count: 3
when: nodes_count | int < 3 and setup_type == "gr"

- name: Chance to correct nodes count for async replication
set_fact:
nodes_count: 2
when: nodes_count | int < 2 and setup_type == "replication"

- name: Create Docker network
shell: docker network create {{ network_name }}
ignore_errors: true

- name: Remove old data folders
shell: 'rm -fr {{ data_dir }}'
loop: "{{ range(1, nodes_count | int + 1) | list }}"

- name: Create data directories
file:
path: "{{ data_dir }}/node{{ item }}/data"
state: directory
mode: '0755'
loop: "{{ range(1, nodes_count | int + 1) | list }}"

- name: Recursively change ownership of a directory
shell: "sudo chown -R 1001:1001 {{ data_dir }}/node{{ item }}/data"
loop: "{{ range(1, nodes_count | int + 1) | list }}"

- name: Setup MySQL group replication
include_tasks: ./tasks/mysql-group-replication-setup.yml
when: setup_type == "gr"

- name: Setup MySQL with async replication
include_tasks: ./tasks/mysql-async-replication-setup.yml
when: setup_type == "replication"

- name: Setup MySQL
include_tasks: tasks/mysql-single.yml
when: setup_type != "gr" and setup_type != "replication"

- name: Wait 10 seconds for setup to finish
pause:
seconds: 10

- name: Create slowlog configuration for mysql nodes
shell: |
docker exec {{ container_prefix }}{{ item }} mysql -uroot -p{{ root_password }} -e "SET GLOBAL slow_query_log='ON'; SET GLOBAL long_query_time=0;"
docker exec {{ container_prefix }}{{ item }} mysql -uroot -p{{ root_password }} -e "SET GLOBAL log_slow_admin_statements=ON; SET GLOBAL log_slow_slave_statements=ON;"
loop: "{{ range(1, nodes_count | int + 1) | list }}"
when: query_source == "slowlog"

- name: Install and add pmm client.
include_tasks: ../tasks/install_pmm_client.yml
vars:
container_name: "{{ container_prefix }}{{ item }}"
loop: "{{ range(1, nodes_count | int + 1) | list }}"

- name: Generate random service name suffix
set_fact:
random_service_name_value: "_{{ 99999 | random + 1 }}"

- name: Add service to pmm server
shell: docker exec {{ container_prefix }}{{ item }} pmm-admin add mysql --query-source={{ query_source }} --username=root --password={{ root_password }} --environment=mysql-gr-dev --cluster=mysql-gr-dev-cluster --replication-set=mysql-gr-replication {{ container_prefix }}{{ item }}{{ random_service_name_value }} --debug 127.0.0.1:3306
loop: "{{ range(1, nodes_count | int + 1) | list }}"
when: setup_type == "gr"

- name: Add service to pmm server
shell: docker exec {{ container_prefix }}{{ item }} pmm-admin add mysql --query-source={{ query_source }} --username=root --password={{ root_password }} --environment=mysql-replication-dev --cluster=mysql-replication-dev-cluster --replication-set=mysql-async-replication {{ container_prefix }}{{ item }}{{ random_service_name_value }} --debug 127.0.0.1:3306
loop: "{{ range(1, nodes_count | int + 1) | list }}"
when: setup_type == "replication"

- name: Add service to pmm server
shell: docker exec {{ container_prefix }}{{ item }} pmm-admin add mysql --query-source={{ query_source }} --username=root --password={{ root_password }} --cluster=mysql-single-dev-cluster --environment=mysql-dev {{ container_prefix }}{{ item }}{{ random_service_name_value }} --debug 127.0.0.1:3306
loop: "{{ range(1, nodes_count | int + 1) | list }}"
when: setup_type != "gr" and setup_type != "replication"

- name: Install sysbench inside of all mysql nodes
shell: docker exec {{ container_prefix }}{{ item }} apt-get install -y sysbench
loop: "{{ range(1, nodes_count | int + 1) | list }}"

- name: Prepare sysbench inside of all mysql nodes
shell: docker exec {{ container_prefix }}{{ item }} mysql -uroot -p{{ root_password }} -e "SET GLOBAL super_read_only = OFF; SET GLOBAL read_only = OFF;"
loop: "{{ range(1, nodes_count | int + 1) | list }}"

- name: Prepare sysbench inside of all mysql nodes
shell: |
docker exec {{ container_prefix }}{{ item }} mysql -uroot -p{{ root_password }} -e "CREATE DATABASE sbtest; CREATE USER 'sbtest'@'localhost' IDENTIFIED BY 'password';"
docker exec {{ container_prefix }}{{ item }} mysql -uroot -p{{ root_password }} -e "GRANT ALL PRIVILEGES ON *.* TO 'sbtest'@'localhost'; CREATE USER 'sbtest'@'127.0.0.1' IDENTIFIED BY 'password';"
docker exec {{ container_prefix }}{{ item }} mysql -uroot -p{{ root_password }} -e "GRANT ALL PRIVILEGES ON *.* TO 'sbtest'@'127.0.0.1'; FLUSH PRIVILEGES;"
loop: "{{ range(1, nodes_count | int + 1) | list }}"
when: setup_type != "gr" and setup_type != "replication" #and mysql_version | replace('_', '') | int >= 84

- name: Prepare sysbench inside of primary mysql node
shell: |
docker exec {{ container_prefix }}1 mysql -uroot -p{{ root_password }} -e "CREATE DATABASE sbtest; CREATE USER 'sbtest'@'localhost' IDENTIFIED BY 'password';"
docker exec {{ container_prefix }}1 mysql -uroot -p{{ root_password }} -e "GRANT ALL PRIVILEGES ON *.* TO 'sbtest'@'localhost'; CREATE USER 'sbtest'@'127.0.0.1' IDENTIFIED BY 'password';"
docker exec {{ container_prefix }}1 mysql -uroot -p{{ root_password }} -e "GRANT ALL PRIVILEGES ON *.* TO 'sbtest'@'127.0.0.1'; FLUSH PRIVILEGES;"
when: setup_type == "gr" or setup_type == "replication" # and mysql_version | replace('_', '') | int >= 84

- name: Prepare data for sysbench inside of all mysql nodes
shell: |
docker exec {{ container_prefix }}{{ item }} sysbench /usr/share/sysbench/oltp_read_write.lua --mysql-host=127.0.0.1 --mysql-port=3306 --mysql-user=sbtest --mysql-password=password --mysql-db=sbtest --tables=10 --table-size=100000 prepare
when: setup_type != "gr" and setup_type != "replication"
loop: "{{ range(1, nodes_count | int + 1) | list }}"

- name: Prepare data for sysbench inside of first mysql nodes
shell: docker exec {{ container_prefix }}1 sysbench /usr/share/sysbench/oltp_read_write.lua --mysql-host=127.0.0.1 --mysql-port=3306 --mysql-user=sbtest --mysql-password=password --mysql-db=sbtest --tables=10 --table-size=100000 prepare
when: setup_type == "gr" or setup_type == "replication"

- name: Run load for sysbench inside of all mysql nodes
shell: docker exec {{ container_prefix }}{{ item }} sysbench /usr/share/sysbench/oltp_read_write.lua --mysql-host=127.0.0.1 --mysql-port=3306 --mysql-user=sbtest --mysql-password=password --mysql-db=sbtest --tables=10 --table-size=100000 --threads=16 --time=60 run
loop: "{{ range(1, nodes_count | int + 1) | list }}"
when: setup_type != "gr" and setup_type != "replication"

- name: Run load for sysbench inside of primary mysql node
shell: docker exec {{ container_prefix }}1 sysbench /usr/share/sysbench/oltp_read_write.lua --mysql-host=127.0.0.1 --mysql-port=3306 --mysql-user=sbtest --mysql-password=password --mysql-db=sbtest --tables=10 --table-size=100000 --threads=16 --time=60 run
when: setup_type == "gr" and setup_type == "replication"

- name: Copy a load file into the container
shell: docker cp ../data/mysql_load.sql {{ container_prefix }}{{ item }}:/mysql_load.sql
loop: "{{ range(1, nodes_count | int + 1) | list }}"

- name: Wait 10 seconds for node to be connected
pause:
seconds: 10

- name: Run load inside of first mysql node
shell: |
docker exec {{ container_prefix }}1 mysql -uroot -p{{ root_password }} -e "CREATE DATABASE school;"
docker exec {{ container_prefix }}1 sh -c "mysql -uroot -p{{ root_password }} school < /mysql_load.sql"
when: setup_type in ['gr', 'replication'] and (mysql_version | replace('_','') | int) >= 80

- name: Run load inside of all mysql nodes
shell: |
docker exec {{ container_prefix }}{{ item }} mysql -uroot -p{{ root_password }} -e "CREATE DATABASE school;"
docker exec {{ container_prefix }}{{ item }} sh -c "mysql -uroot -p{{ root_password }} school < /mysql_load.sql"
loop: "{{ range(1, nodes_count | int + 1) | list }}"
when: setup_type not in ['gr', 'replication'] and (mysql_version | replace('_','') | int) >= 80
Loading