diff --git a/justfile b/justfile index 8a98edf..3063c15 100644 --- a/justfile +++ b/justfile @@ -45,6 +45,14 @@ seed-firebird: echo "SELECT RDB\$RELATION_NAME FROM RDB\$RELATIONS WHERE RDB\$SYSTEM_FLAG = 0 AND RDB\$VIEW_BLR IS NULL;" \ | docker exec -i db-firebird isql -user alice -password fake_password /var/lib/firebird/data/mirror.fdb +seed-firebird-large: + echo "Seeding Firebird..." + docker exec -i db-firebird isql -user alice -password fake_password /var/lib/firebird/data/mirror.fdb < ./scripts/firebird/seed-large.sql + + echo "Verifying Firebird tables..." + echo "SELECT RDB\$RELATION_NAME FROM RDB\$RELATIONS WHERE RDB\$SYSTEM_FLAG = 0 AND RDB\$VIEW_BLR IS NULL;" \ + | docker exec -i db-firebird isql -user alice -password fake_password /var/lib/firebird/data/mirror.fdb + seed-mssql: echo "Seeding MSSQL..." docker exec -i rust-dev sqlcmd -S "db-mssql,1433" -U sa -P "$MSSQL_SA_PASSWORD" -N disable -i /app/scripts/mssql/seed.sql diff --git a/scripts/firebird/seed-large.sql b/scripts/firebird/seed-large.sql new file mode 100644 index 0000000..4492faa --- /dev/null +++ b/scripts/firebird/seed-large.sql @@ -0,0 +1,259 @@ +SET SQL DIALECT 3; +SET BAIL ON; +SET AUTODDL OFF; + +CREATE TABLE users ( + id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + email VARCHAR(255) NOT NULL UNIQUE, + name VARCHAR(255), + payload BLOB SUB_TYPE TEXT, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); + +COMMIT; + +INSERT INTO users (email, name, payload) +VALUES ('alice@example.com', 'Alice', 'Alice seed data'); + +INSERT INTO users (email, name, payload) +VALUES ('bob@example.com', 'Bob', 'Bob seed data'); + +COMMIT; + +/* + * Each procedure call generates approximately 128 MiB: + * + * 128 rows + * × 128 chunks per row + * × 8191 bytes per chunk + * = approximately 128 MiB + * + * 40 calls = approximately 5 GiB. + */ + +SET TERM ^; + +CREATE PROCEDURE seed_users_batch ( + p_rows INTEGER, + p_chunks_per_row INTEGER +) + AS +DECLARE VARIABLE v_row_index INTEGER; + DECLARE VARIABLE v_chunk_index INTEGER; + DECLARE VARIABLE v_uuid VARCHAR(36); + DECLARE VARIABLE v_chunk VARCHAR(8191); + DECLARE VARIABLE v_payload BLOB SUB_TYPE TEXT; +BEGIN + v_row_index = 0; + + WHILE (v_row_index < p_rows) DO +BEGIN + v_payload = NULL; + v_chunk_index = 0; + + WHILE (v_chunk_index < p_chunks_per_row) DO +BEGIN + /* + * Generate a different chunk to avoid producing a completely + * uniform BLOB. + */ + v_chunk = RPAD( + UUID_TO_CHAR(GEN_UUID()), + 8191, + UUID_TO_CHAR(GEN_UUID()) + ); + + v_payload = BLOB_APPEND(v_payload, v_chunk); + v_chunk_index = v_chunk_index + 1; +END + + v_uuid = UUID_TO_CHAR(GEN_UUID()); + +INSERT INTO users ( + email, + name, + payload +) +VALUES ( + :v_uuid || '@example.test', + 'Seed User ' || :v_uuid, + :v_payload + ); + +v_row_index = v_row_index + 1; +END +END^ + +SET TERM ;^ + +/* Batch 01 — approximately 128 MiB */ +EXECUTE PROCEDURE seed_users_batch(128, 128); +COMMIT; + +/* Batch 02 */ +EXECUTE PROCEDURE seed_users_batch(128, 128); +COMMIT; + +/* Batch 03 */ +EXECUTE PROCEDURE seed_users_batch(128, 128); +COMMIT; + +/* Batch 04 */ +EXECUTE PROCEDURE seed_users_batch(128, 128); +COMMIT; + +/* Batch 05 */ +EXECUTE PROCEDURE seed_users_batch(128, 128); +COMMIT; + +/* Batch 06 */ +EXECUTE PROCEDURE seed_users_batch(128, 128); +COMMIT; + +/* Batch 07 */ +EXECUTE PROCEDURE seed_users_batch(128, 128); +COMMIT; + +/* Batch 08 — approximately 1 GiB total */ +EXECUTE PROCEDURE seed_users_batch(128, 128); +COMMIT; + +/* Batch 09 */ +EXECUTE PROCEDURE seed_users_batch(128, 128); +COMMIT; + +/* Batch 10 */ +EXECUTE PROCEDURE seed_users_batch(128, 128); +COMMIT; + +/* Batch 11 */ +EXECUTE PROCEDURE seed_users_batch(128, 128); +COMMIT; + +/* Batch 12 */ +EXECUTE PROCEDURE seed_users_batch(128, 128); +COMMIT; + +/* Batch 13 */ +EXECUTE PROCEDURE seed_users_batch(128, 128); +COMMIT; + +/* Batch 14 */ +EXECUTE PROCEDURE seed_users_batch(128, 128); +COMMIT; + +/* Batch 15 */ +EXECUTE PROCEDURE seed_users_batch(128, 128); +COMMIT; + +/* Batch 16 — approximately 2 GiB total */ +EXECUTE PROCEDURE seed_users_batch(128, 128); +COMMIT; + +/* Batch 17 */ +EXECUTE PROCEDURE seed_users_batch(128, 128); +COMMIT; + +/* Batch 18 */ +EXECUTE PROCEDURE seed_users_batch(128, 128); +COMMIT; + +/* Batch 19 */ +EXECUTE PROCEDURE seed_users_batch(128, 128); +COMMIT; + +/* Batch 20 */ +EXECUTE PROCEDURE seed_users_batch(128, 128); +COMMIT; + +/* Batch 21 */ +EXECUTE PROCEDURE seed_users_batch(128, 128); +COMMIT; + +/* Batch 22 */ +EXECUTE PROCEDURE seed_users_batch(128, 128); +COMMIT; + +/* Batch 23 */ +EXECUTE PROCEDURE seed_users_batch(128, 128); +COMMIT; + +/* Batch 24 — approximately 3 GiB total */ +EXECUTE PROCEDURE seed_users_batch(128, 128); +COMMIT; + +/* Batch 25 */ +EXECUTE PROCEDURE seed_users_batch(128, 128); +COMMIT; + +/* Batch 26 */ +EXECUTE PROCEDURE seed_users_batch(128, 128); +COMMIT; + +/* Batch 27 */ +EXECUTE PROCEDURE seed_users_batch(128, 128); +COMMIT; + +/* Batch 28 */ +EXECUTE PROCEDURE seed_users_batch(128, 128); +COMMIT; + +/* Batch 29 */ +EXECUTE PROCEDURE seed_users_batch(128, 128); +COMMIT; + +/* Batch 30 */ +EXECUTE PROCEDURE seed_users_batch(128, 128); +COMMIT; + +/* Batch 31 */ +EXECUTE PROCEDURE seed_users_batch(128, 128); +COMMIT; + +/* Batch 32 — approximately 4 GiB total */ +EXECUTE PROCEDURE seed_users_batch(128, 128); +COMMIT; + +/* Batch 33 */ +EXECUTE PROCEDURE seed_users_batch(128, 128); +COMMIT; + +/* Batch 34 */ +EXECUTE PROCEDURE seed_users_batch(128, 128); +COMMIT; + +/* Batch 35 */ +EXECUTE PROCEDURE seed_users_batch(128, 128); +COMMIT; + +/* Batch 36 */ +EXECUTE PROCEDURE seed_users_batch(128, 128); +COMMIT; + +/* Batch 37 */ +EXECUTE PROCEDURE seed_users_batch(128, 128); +COMMIT; + +/* Batch 38 */ +EXECUTE PROCEDURE seed_users_batch(128, 128); +COMMIT; + +/* Batch 39 */ +EXECUTE PROCEDURE seed_users_batch(128, 128); +COMMIT; + +/* Batch 40 — approximately 5 GiB total */ +EXECUTE PROCEDURE seed_users_batch(128, 128); +COMMIT; + +DROP PROCEDURE seed_users_batch; + +COMMIT; + +SELECT + COUNT(*) AS user_count, + CAST(SUM(OCTET_LENGTH(payload)) / 1073741824.0 AS DECIMAL(18, 2)) + AS payload_size_gib +FROM users; + +COMMIT; \ No newline at end of file diff --git a/src/domain/firebird/backup.rs b/src/domain/firebird/backup.rs index 959bf9e..3d34dad 100644 --- a/src/domain/firebird/backup.rs +++ b/src/domain/firebird/backup.rs @@ -23,6 +23,7 @@ pub async fn run( let start = Instant::now(); let output = Command::new("gbak") .arg("-b") + .arg("-g") .arg("-v") .arg("-user").arg(&cfg.username) .arg("-password").arg(&cfg.password)