@opZ1ca and me ran into a small big problem yesterday.
In short, a TeamSpeak server seems to generate a broken snapshot.
The server version is 3.13.7
and it’s using SQLite at the moment.
We tried to create a snapshot and deploy it immediately after. However, running serversnapshotdeploy version=3 data=KLUv\/aS4h[...]
takes a few seconds only to return error id=512 msg=invalid\sclientID
.
I assume this is caused by a corrupted database. So I ran a small script to check the foreign key integrity:
# No need to test `perm_channel_clients`, `messages`, `custom_fields`, and `complains`, as they are empty.
import sqlite3
con = sqlite3.connect("ts3server.sqlitedb")
# select ALL unique ids from client_properties
cur = con.cursor()
cur.execute("SELECT DISTINCT id FROM client_properties")
rows = cur.fetchall()
# check if of each id, there exists a client with that client_id
print(f"Checking integrity of client_properties for {len(rows)} unique ids")
for row in rows:
cur.execute("SELECT * FROM clients WHERE client_id = ?", (row[0],))
if len(cur.fetchall()) == 0:
print(f"client_properties id {row[0]} has no corresponding client")
# get all group_server_to_client id1s
cur.execute("SELECT DISTINCT id1 FROM group_server_to_client")
rows = cur.fetchall()
# check if of each id, there exists a client with that client_id
print(f"Checking integrity of group_server_to_client for {len(rows)} unique ids")
for row in rows:
cur.execute("SELECT * FROM clients WHERE client_id = ?", (row[0],))
if len(cur.fetchall()) == 0:
print(f"group_server_to_client id1 {row[0]} has no corresponding client")
# get all group_channel_to_client id1s
cur.execute("SELECT DISTINCT id1 FROM group_channel_to_client")
rows = cur.fetchall()
# check if of each id, there exists a client with that client_id
print(f"Checking integrity of group_channel_to_client for {len(rows)} unique ids")
for row in rows:
cur.execute("SELECT * FROM clients WHERE client_id = ?", (row[0],))
if len(cur.fetchall()) == 0:
print(f"group_channel_to_client id1 {row[0]} has no corresponding client")
# get all perm_client id1s
cur.execute("SELECT DISTINCT id1 FROM perm_client")
rows = cur.fetchall()
# check if of each id, there exists a client with that client_id
print(f"Checking integrity of perm_client for {len(rows)} unique ids")
for row in rows:
cur.execute("SELECT * FROM clients WHERE client_id = ?", (row[0],))
if len(cur.fetchall()) == 0:
print(f"perm_client id1 {row[0]} has no corresponding client")
But it prints no errors:
Checking integrity of client_properties for 11759 unique ids
Checking integrity of group_server_to_client for 11484 unique ids
Checking integrity of group_channel_to_client for 148 unique ids
Checking integrity of perm_client for 29 unique ids
So what could cause such an error? (Why is there no useful output…?) Can this be fixed without nuking the DB?