====== How to upgrade nextcloud mysql to postgresql ====== ===== Upgrade the server ===== This is optional of course. apt update # apt remove --purge -y postgresql* # if you want to delete all postgresql db & versions first. YMMV! apt upgrade -y && apt autoremove -y && apt dist-upgrade -y do-release-upgrade # yes, reboot when asked Login again on your server, and: apt autoremove -y apt install postgresql postgresql-client postgresql-client-common ====== Using the mattermost migration script ====== You will see that it is more or less broken though :-/ cd /root mkdir mm_migration cd mm_migration systemctl stop mattermost wget https://github.com/mattermost/migration-assist/releases/download/v0.3/migration-assist-Linux-x86_64.tar.gz tar xvzf migration-assist-Linux-x86_64.tar.gz && rm migration-assist-Linux-x86_64.tar.gz Set these two according to your setup in your sessions. They will be used more than once. Eg: MYSQL_DSN="matteruser:mysqlpassword@tcp(127.0.0.1:3306)/mattermost" POSTGRES_DSN="postgres://matteruser:postgresqlpassword@127.0.0.1:5432/mattermost" ====== Create database and user ====== su - postgres dropdb -f mattermost psql DROP DATABASE mattermost; CREATE DATABASE mattermost; \connect mattermost CREATE USER matteruser WITH PASSWORD 'LJFHzzERLhf56'; ALTER ROLE "matteruser" WITH LOGIN; GRANT ALL PRIVILEGES ON DATABASE mattermost to matteruser; ALTER DATABASE mattermost OWNER TO matteruser; GRANT USAGE, CREATE ON SCHEMA PUBLIC TO matteruser; ALTER SCHEMA public OWNER TO matteruser; GRANT ALL ON SCHEMA public to matteruser; ALTER user matteruser in database mattermost set search_path to 'public'; \q # Exit user postgres [[ $USER = 'root' ]] || exit vi /etc/postgresql/{version}/main/pg_hba.conf # Add this line BEFORE the "local all all peer": local mattermost matteruser md5 # restart postgresql systemctl reload postgresql You can test it with ''psql %%--%%dbname=mattermost %%--%%username=matteruser %%--%%password'' and: \connect mattermost -- You are now connected to database "mattermost" as user "matteruser" -- \q Then: mysql -u root mattermost -- you may need this -- -- ALTER USER 'matteruser'@'%' IDENTIFIED WITH mysql_native_password BY 'mysqlpassword'; -- -- Fix also some data that does not fit in the pg target -- UPDATE LinkMetadata SET URL = left(URL, 2000) WHERE length(URL) > 2000; # For this error: # ERROR mysql: Failed to connect to mysql at "127.0.0.1" (port 3306) as user "matteruser": Condition QMYND:MYSQL-UNSUPPORTED-AUTHENTICATION was signalled. # We do this (once!) echo -e "\n[mysqld]\ndefault-authentication-plugin=mysql_native_password\n" >> /etc/mysql/mysql.cnf systemctl restart mysql ====== pgloader hell ====== Build pgloader from source (other ways sometimes fails): apt install libssl-dev freetds-dev cd /root/mm_migration/ mkdir pgloader_from_source cd pgloader_from_source wget https://github.com/dimitri/pgloader/releases/download/v3.6.9/pgloader-bundle-3.6.9.tgz tar xvzf pgloader-bundle-3.6.9.tgz && rm pgloader-bundle-3.6.9.tgz cd pgloader-bundle-3.6.9/ apt install sbcl make make DYNSIZE=32000 pgloader mv bin/pgloader /root/mm_migration/ cd /root/mm_migration/ /root/mm_migration/pgloader --version # pgloader version "3.6.9" rm -r pgloader_from_source ====== Do the migration ====== cd ~/mm_migration ./migration-assist mysql "$MYSQL_DSN" ./migration-assist postgres "$POSTGRES_DSN" --run-migrations --mattermost-version="10.4.2" # see "/opt/mattermost/bin/mattermost version" ./migration-assist pgloader --mysql="$MYSQL_DSN" --postgres="$POSTGRES_DSN" > migration.load sed -i "s/_mem to '[^']*'/_mem to '12000MB'/" migration.load sed -i "s/workers = [0-9]*/workers = 2/" migration.load sed -i "s/prefetch rows = [0-9]*/prefetch rows = 2000/" migration.load ./pgloader migration.load | tee migration.log Small fixes: # This may fail because of "tsvector" maximum size: # ./migration-assist postgres post-migrate "$POSTGRES_DSN" # So we do it manually: use 1000000 or shorter values (like 500000) su - postgres psql \connect mattermost CREATE INDEX IF NOT EXISTS idx_posts_message_txt ON public.posts USING gin(to_tsvector('english', substring(message,500000))); CREATE INDEX IF NOT EXISTS idx_fileinfo_content_txt ON public.fileinfo USING gin(to_tsvector('english', substring(content,500000))); \q [[ $USER = 'root' ]] || exit ./migration-assist postgres post-migrate "$POSTGRES_DSN" # terminates the job # Extra stuff to migrate: for job in boards playbooks calls; do ./migration-assist pgloader $job --mysql="$MYSQL_DSN" --postgres="$POSTGRES_DSN" > $job.load ./pgloader $job.load | tee $job.log done ====== Enable postgresql database in mattermost config ====== cp /opt/mattermost/config/config.json /opt/mattermost/config/config.json-$(date +'%Y%m%d-%H%M%S') sed -i 's/"DriverName": "mysql"/"DriverName": "postgres"/' /opt/mattermost/config/config.json sed -i '/"DataSource"/r"DataSource": "'$POSTGRES_DSN'"?sslmode=disable&connect_timeout=10",' /opt/mattermost/config/config.json And start the service: cd /opt/mattermost/ sudo -u mattermost ./bin/mattermost If all is OK, re-enable mattermost: systemctl start mattermost tail -F /opt/mattermost/logs/mattermost.log ====== Cleanup ====== rm -r /root/mm_migration/ # drop mysql database if and only when you are sure the migration is OK