From 054adaf7be881ec0bfb264a1f21df072bfa4eea5 Mon Sep 17 00:00:00 2001 From: aitbc Date: Tue, 21 Apr 2026 22:00:47 +0200 Subject: [PATCH] feat: switch SQLite to WAL mode and disable Btrfs CoW for data directory - Change SQLite journal mode from DELETE to WAL for better concurrency - Add chattr +C to /var/lib/aitbc in setup.sh to disable Btrfs Copy-on-Write - Add fallback logging when chattr is unavailable or fails - Prevent SQLite corruption on Btrfs filesystems by ensuring overwrite-in-place behavior --- .windsurf/skills/ssh-access-patterns.md | 69 +++++++++++++++++++ .../src/aitbc_chain/database.py | 2 +- scripts/setup.sh | 7 ++ 3 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 .windsurf/skills/ssh-access-patterns.md diff --git a/.windsurf/skills/ssh-access-patterns.md b/.windsurf/skills/ssh-access-patterns.md new file mode 100644 index 00000000..d9bd45ed --- /dev/null +++ b/.windsurf/skills/ssh-access-patterns.md @@ -0,0 +1,69 @@ +# SSH Access Patterns for AITBC Nodes + +## Purpose +Document SSH access patterns for all AITBC nodes in the infrastructure. + +## Node Access Patterns + +### aitbc (localhost) +Direct access - no SSH required. +```bash +# Run commands directly on localhost +echo "command" +systemctl restart service-name +``` + +### aitbc1 +Direct SSH access. +```bash +ssh aitbc1 +# Or execute single command +ssh aitbc1 "command" +``` + +### gitea-runner (also hosts aitbc2) +Direct SSH access. aitbc2 blockchain node runs on the same host. +```bash +ssh gitea-runner +# Or execute single command +ssh gitea-runner "command" +``` + +## Common Operations + +### Check service status on aitbc1 +```bash +ssh aitbc1 "systemctl status aitbc-blockchain-node --no-pager" +``` + +### Restart service on gitea-runner (aitbc2) +```bash +ssh gitea-runner "systemctl restart aitbc-blockchain-node" +``` + +### Copy file to aitbc1 +```bash +scp /path/to/file aitbc1:/path/to/destination +``` + +### Execute script on gitea-runner +```bash +ssh gitea-runner "bash /path/to/script.sh" +``` + +## Multi-Node Operations + +### Run command on all remote nodes +```bash +for node in aitbc1 gitea-runner; do + ssh "$node" "systemctl status aitbc-blockchain-node --no-pager" +done +``` + +### Check block heights across all nodes +```bash +for node in aitbc1 gitea-runner; do + echo "=== $node ===" + ssh "$node" "curl -s http://localhost:8006/rpc/bestBlock | jq '.height'" +done +``` diff --git a/apps/blockchain-node/src/aitbc_chain/database.py b/apps/blockchain-node/src/aitbc_chain/database.py index d249a708..dc93524a 100755 --- a/apps/blockchain-node/src/aitbc_chain/database.py +++ b/apps/blockchain-node/src/aitbc_chain/database.py @@ -24,7 +24,7 @@ _engine = create_engine(f"sqlite:///{settings.db_path}", echo=False) @event.listens_for(_engine, "connect") def set_sqlite_pragma(dbapi_connection, connection_record): cursor = dbapi_connection.cursor() - cursor.execute("PRAGMA journal_mode=DELETE") + cursor.execute("PRAGMA journal_mode=WAL") cursor.execute("PRAGMA synchronous=NORMAL") cursor.execute("PRAGMA cache_size=-64000") cursor.execute("PRAGMA temp_store=MEMORY") diff --git a/scripts/setup.sh b/scripts/setup.sh index 53cddd56..e1582008 100755 --- a/scripts/setup.sh +++ b/scripts/setup.sh @@ -114,6 +114,13 @@ setup_runtime_directories() { chown root:root /var/log/aitbc chown root:root /etc/aitbc + # Disable Btrfs CoW on data directory to prevent SQLite corruption + # SQLite expects overwrite-in-place behavior, which conflicts with CoW + if command -v chattr >/dev/null 2>&1; then + chattr +C /var/lib/aitbc 2>/dev/null || log "Could not disable CoW (not Btrfs or no permissions)" + log "Disabled Btrfs CoW on /var/lib/aitbc to prevent SQLite corruption" + fi + # Create README files echo "# AITBC Runtime Data Directory" > /var/lib/aitbc/README.md echo "# Keystore for blockchain keys (SECURE)" > /var/lib/aitbc/keystore/README.md