long2ice / meilisync

Realtime sync data from MySQL/PostgreSQL/MongoDB to Meilisearch
https://github.com/long2ice/meilisync
Apache License 2.0
260 stars 40 forks source link

fix: postgres errors #80

Closed lasseintree closed 8 months ago

lasseintree commented 8 months ago

Having tried to implement meilisync on a postgres database I encountered some errors

I have also made a healthcheck bash script that can be used for a healthcheck when using meilisync as a service in docker compose. It runs meilisync check and if errors occur, then it runs meilisync refresh on the tables that are out of sync, it then returns exit code 1, and if meilisync check returns no errors it returns exit code 0, and does not run meilisync refresh .

#!/bin/bash

tables=$(meilisync check 2>&1 | grep 'ERROR' | awk -F '"' '{print $2}' | awk -F '.' '{print $2}')
args=""
if echo "$tables" | grep -q "\w"; then
    for table in $tables; do
        args="$args -t $table"
    done
    meilisync refresh $args 2> /dev/null
    false
else
    true
fi

I wasn't sure if I should include it in the pull request or not, but adding it to the repo would make it easy for people using meilisync to have a healthcheck in docker compose

    healthcheck:
      test: ["CMD-SHELL", "./meilisync-healthcheck.sh"]
      interval: 1h
      timeout: 10m
      retries: 2

When jumping between branches with meilisync requiring wal_level>=logical and branches not having wal2json it would not allow the database to start without wal2json and an active replication slot. I have made an sql script to drop the meilisync replication slot, to be used when you want to shut down your postgres database, so you can start your postgres database without wal2json. When you want to drop a replication slot it cannot be active, but when terminating the process it will try to start up again, so you have to drop it before it starts up again, this script will try doing it 5 times, since it is sometimes not successful in the first try.

CREATE OR REPLACE FUNCTION drop_replication_slot_with_retry() RETURNS VOID AS $$
DECLARE
    attempts INT := 0;
BEGIN
    LOOP
        BEGIN
            EXECUTE 'SELECT pg_drop_replication_slot(''meilisync'')';

            RAISE NOTICE 'Replication slot "meilisync" has been removed';
            EXIT;
        EXCEPTION
            WHEN others THEN
                IF attempts >= 5 THEN
                    RAISE NOTICE 'Replication slot "meilisync" is still active after 5 attempts. Aborting...';
                    RAISE;
                ELSIF SQLSTATE = '55006' THEN
                    attempts := attempts + 1;

                    EXECUTE 'SELECT pg_terminate_backend(pid) FROM pg_stat_replication';

                    RAISE NOTICE 'Replication slot "meilisync" is active. Terminating backend and retrying...';

                    PERFORM pg_sleep(1); 
                ELSE
                    RAISE;
                END IF;
        END;
    END LOOP;
END;
$$ LANGUAGE plpgsql;
SELECT drop_replication_slot_with_retry();
long2ice commented 8 months ago

Thanks! Please run make style local

long2ice commented 8 months ago

Thanks!