Repository navigation
[Bug] Cannot add a semi-sync replica to existing cluster #141
Copy link
Copy link
Closed
Labels
bugSomething isn't workingSomething isn't workingreplicationAsynchronous replicationAsynchronous replication
Description
Describe the bug
I have a running semi-sync replica cluster with 1 master and 1 replica.
Trying to add a new replica fails since it cannot find binlogs required for replica
2023-06-19 9:47:12 12 [Note] Master connection name: 'mariadb-operator' Master_info_file: '[email protected]' Relay_info_file: '[email protected]'
2023-06-19 9:47:12 12 [Note] 'CHANGE MASTER TO executed'. Previous state master_host='', master_port='3306', master_log_file='', master_log_pos='4'. New state master_host='mariadb-myns-0.mariadb-myns.myns.svc.cluster.local', master_port='3306', master_log_file='', master_log_pos='4'.
2023-06-19 9:47:12 12 [Note] Previous Using_Gtid=No. New Using_Gtid=Current_Pos
2023-06-19 9:47:12 13 [Note] Master 'mariadb-operator': Slave I/O thread: Start semi-sync replication to master '[email protected]:3306' in log '' at position 4
2023-06-19 9:47:12 14 [Note] Master 'mariadb-operator': Slave SQL thread initialized, starting replication in log 'FIRST' at position 4, relay log './[email protected]' position: 4; GTID position ''
2023-06-19 9:47:12 13 [Note] Master 'mariadb-operator': Slave I/O thread: connected to master '[email protected]:3306',replication starts at GTID position ''
2023-06-19 9:47:12 13 [ERROR] Master 'mariadb-operator': Error reading packet from server: Could not find GTID state requested by slave in any binlog files. Probably the slave state is too old and required binlog files have been purged. (server_errno=1236)
2023-06-19 9:47:12 13 [ERROR] Master 'mariadb-operator': Slave I/O: Got fatal error 1236 from master when reading data from binary log: 'Could not find GTID state requested by slave in any binlog files. Probably the slave state is too old and required binlog files have been purged.', Internal MariaDB error code: 1236
2023-06-19 9:47:12 13 [Note] Master 'mariadb-operator': Slave I/O thread exiting, read up to log 'FIRST', position 4; GTID position , master mariadb-myns-0.mariadb-myns.myns.svc.cluster.local:3306
2023-06-19 9:47:12 13 [Note] Master 'mariadb-operator': Failed to gracefully kill our active semi-sync connection with primary. Silently closing the connection.
Expected behaviour
New replica initializes properly.
Steps to reproduce the bug
- Create cluster with semi-sync replication and 2 replicas
- Run the cluster until older binlog file are purged
- Try to scale replicas to 3
Environment details:
- Kubernetes version: 1.26.5
- mariadb-operator version: v0.0.15
- Install method: helm
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't workingreplicationAsynchronous replicationAsynchronous replication
Activity
mmontes11 commentedon Jun 19, 2023
Hey @fchiacchiaretta ! thanks for reporting this 🙏🏻
Unfortunately I didn't manage to reproduce the issue, it scaled from 2 to 3 after running this MariaDB for a couple of hours. Could you provide your
MariaDBresource?How did this happened? Was it somehow triggered by a MariaDB internal process or performed manually? It would be great to understand this first to reproduce it and have a better context. The error
1236can happen due to multiple reasons and there are some remediations for it that can be potentially applied via spec.myCnf.cc @grooverdan
grooverdan commentedon Jun 19, 2023
never mind. See that is standard "CHANGE MASTER" output.
fchiacchiaretta commentedon Jun 20, 2023
Hello @mmontes11 ,
thank you for your answer.
Here my
MariaDBresourceI did no special operation to trigger binlog purging, but on master pod I see that some files have been purged:
I checked for
expire_log_daysandbinlog_expire_logs_secondsbut it seems that neither of them have been set.I'm trying to reproduce the issue on a test cluster too, I'll be back if I have some additional results.
mmontes11 commentedon Jun 20, 2023
@grooverdan we are not providing the
MASTER_LOG_FILE, but we do specifyMASTER_USE_GTIDalways. Would this be a problem with the @fchiacchiaretta's configuration?mariadb-operator/pkg/client/client.go
Line 278 in 3f5e6a3
grooverdan commentedon Jun 20, 2023
expire_log_daysis actually in the container default. (which I'm open to remove from the defaults).expire_logs_days=0in the configuration should override this. Check withselect @@expire_logs_days.So
ConfigureReplicais expecting the full binary logs to exist? Is a mariadb-backup stream the entire datadir as a point-in-time copy from the primary to replica if the logs are missing required?fchiacchiaretta commentedon Jun 20, 2023
@grooverdan I can confirm
expire_logs_daysis set to 10 as per defaultmmontes11 commentedon Jun 20, 2023
Not quite sure about this. ConfigureReplica performs the following
CHANGE MASTERstatement:which does not take into account the
master_log_fileat any point. I'm guessing that ifmaster_log_fileis empty, it tries to default to a binary log that in this case was deleted. Does this behaviour depend somehow on the GTID? By default we usecurrent_posbut we support specifyingslave_posvia spec.replication.replica.gtid = SlavePosGood question, unfortunately I'm not aware of mariabackuip internals. Maybe something to discuss with the MariaDB team?
I will add
expire_logs_dayshere as well to avoid this situations in the future if that makes sense.mariadb-operator/pkg/builder/statefulset_builder.go
Line 205 in 3f5e6a3
fchiacchiaretta commentedon Jun 20, 2023
As far as I know, setting up a new replica via mariabackup is the easiest way, docs for reference.
Having a sane default for
expire_logs_daysis good for production setup, as the PVC would fill up very fast with old binlogs that would be rarely used.grooverdan commentedon Jun 21, 2023
note came across this, MDEV-27437, which comes into play if the mariadb backup donor isn't the same version as replica.
fchiacchiaretta commentedon Jun 21, 2023
Upon further testing, I found that this issue occurs also when deleting one of the already configured and running replica pods, here the steps I followed to reproduce:
Upon restart, MariaDB properly restarts replication with the correct position and GTID
Checking logs on master pod, we can notice that server_id is wrong (stop with id 12, but start with id 1)
After that, mariadb-operator kicks in and reconfigure replica with ConfigureReplica, stopping Slave Thread, resetting slave position and setting server_id programmatically (10 + podIndex)
Since replication restarts
in log 'FIRST' at position 4, if binlogs were purged replication fails.mmontes11 commentedon Jun 21, 2023
@fchiacchiaretta awesome investigation, thanks for the level of detail 💯 🥇
I've managed to reproduce the issue by:
MariaDBinstancemax-binlog-size=4096andbinlog_expire_logs_seconds=10As a result, the binary logs got deleted
At this point, upscaling to 3 results in the following logs in the new replica:
This happens with both MariaDB version
10.11.3and10.6.13. Having a look now 👀mmontes11 commentedon Jun 21, 2023
I've manually managed to solve the issue by taking a backup from the primary and restoring it on the failing replica. Basically following this guide:
The steps involved were:
mariadb-operatorStatefulSetto mount the backup PVCinitContainerto restore the backup. This could be improved to conditionally restore the backup if/var/lib/mysqlis empty (no PVC)mariadb-operatorLogs from the failing replica after doing this:
This would be hard to automate and requires supporting
mariabackup, contributions are welcome!For the time being I think the best thing will be acknowledging this limitation and allow the user to configure the binlog:
The defaults were taken from the oficial MariaDB image:
Regarding this, it could be related to the fact that the
server_idis ephemeral and set up on the fly by the operator here:mariadb-operator/pkg/controller/replication/config.go
Line 98 in 3f5e6a3
mariadb-operator/pkg/controller/replication/config.go
Line 119 in 3f5e6a3
We could use an
initContainerand dynamically set theserver_idin a configuration time, but it will be worth ensuring that this is related to the problem.grooverdan commentedon Jun 22, 2023
Note the
mariabackupneeds to be--prepared. This will apply redo log changes made during the backup.Steps for a mariabackup based provisioning of a replica:
note obviously any port, I couldn't see a "just pick one" socat option, but all should be free in the container namespace.
other socat options like OPENSSL-LISTEN can also be used too. Requires all the usual tls stuff however. If network encryption is required an
openssl encin the pipeline with a random operator password is probably easier.backupuser is the database user with required grants.
read gtid from /var/lib/mysql/.mariabackup/xtrabackup_binlog_info
Not sure if its easy, but if provisioning multiple replicas at this point this directory could be copied. Or multiple destinations in step 2 like:
or more than 2:
ref: https://unix.stackexchange.com/questions/28503/how-can-i-send-stdout-to-multiple-commands
replica can be started with standard entrypoint now.
using gtid from step 3
ref: https://mariadb.com/kb/en/setting-up-a-replica-with-mariabackup/#gtids
52 remaining items
github-actions commentedon Apr 9, 2025
This issue is stale because it has been open 60 days with no activity.
github-actions commentedon Jun 10, 2025
This issue is stale because it has been open 60 days with no activity.
mmontes11 commentedon Jun 26, 2025
We have made some progress by supporting
PhysicalBackups: #1266This will be used for rebuilding replicas in further releases.
github-actions commentedon Aug 26, 2025
This issue is stale because it has been open 60 days with no activity.
github-actions commentedon Sep 28, 2025
This issue was closed because it has been stalled for 30 days with no activity.
mmontes11 commentedon Sep 29, 2025
To be addressed as part of: #1423