157 lines
4.5 KiB
Markdown
157 lines
4.5 KiB
Markdown
|
|
# Fix Blockscout Schema/Connection Mismatch
|
||
|
|
|
||
|
|
## Problem
|
||
|
|
|
||
|
|
The `migrations_status` table exists when checked from postgres, but Blockscout can't see it and crashes with:
|
||
|
|
```
|
||
|
|
ERROR 42P01 (undefined_table) relation "migrations_status" does not exist
|
||
|
|
```
|
||
|
|
|
||
|
|
## Root Cause
|
||
|
|
|
||
|
|
This typically indicates:
|
||
|
|
1. **Schema mismatch**: Table exists in a different schema than Blockscout is searching
|
||
|
|
2. **Database mismatch**: Blockscout connecting to different database
|
||
|
|
3. **Search path issue**: PostgreSQL `search_path` doesn't include the schema
|
||
|
|
4. **Connection string issue**: DATABASE_URL points to wrong database/schema
|
||
|
|
|
||
|
|
## Diagnosis Commands
|
||
|
|
|
||
|
|
Run these to identify the issue:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# From VMID 5000
|
||
|
|
|
||
|
|
# 1. Check what schema the table is in
|
||
|
|
docker exec blockscout-postgres psql -U blockscout -d blockscout -c "
|
||
|
|
SELECT table_schema, table_name
|
||
|
|
FROM information_schema.tables
|
||
|
|
WHERE table_name = 'migrations_status';
|
||
|
|
"
|
||
|
|
|
||
|
|
# 2. Check current search_path
|
||
|
|
docker exec blockscout-postgres psql -U blockscout -d blockscout -c "SHOW search_path;"
|
||
|
|
|
||
|
|
# 3. Check Blockscout DATABASE_URL
|
||
|
|
BLOCKSCOUT_CONTAINER=$(docker ps -a | grep blockscout | grep -v postgres | awk '{print $1}' | head -1)
|
||
|
|
docker inspect --format='{{range .Config.Env}}{{println .}}{{end}}' $BLOCKSCOUT_CONTAINER | grep DATABASE_URL
|
||
|
|
|
||
|
|
# 4. Test table access with explicit schema
|
||
|
|
docker exec blockscout-postgres psql -U blockscout -d blockscout -c "
|
||
|
|
SELECT COUNT(*) FROM public.migrations_status;
|
||
|
|
"
|
||
|
|
```
|
||
|
|
|
||
|
|
## Solutions
|
||
|
|
|
||
|
|
### Solution 1: Fix Search Path
|
||
|
|
|
||
|
|
If table is in `public` schema but search_path doesn't include it:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
docker exec blockscout-postgres psql -U blockscout -d blockscout << 'SQL'
|
||
|
|
ALTER DATABASE blockscout SET search_path = public, "$user";
|
||
|
|
\c blockscout
|
||
|
|
SELECT set_config('search_path', 'public', false);
|
||
|
|
SQL
|
||
|
|
```
|
||
|
|
|
||
|
|
### Solution 2: Verify DATABASE_URL
|
||
|
|
|
||
|
|
Check Blockscout's DATABASE_URL matches the actual database:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Check what Blockscout is using
|
||
|
|
BLOCKSCOUT_CONTAINER=$(docker ps -a | grep blockscout | grep -v postgres | awk '{print $1}' | head -1)
|
||
|
|
docker inspect --format='{{range .Config.Env}}{{println .}}{{end}}' $BLOCKSCOUT_CONTAINER | grep DATABASE_URL
|
||
|
|
|
||
|
|
# Should be: postgresql://blockscout:blockscout@postgres:5432/blockscout
|
||
|
|
# If different, update docker-compose.yml
|
||
|
|
```
|
||
|
|
|
||
|
|
### Solution 3: Recreate migrations_status in Correct Schema
|
||
|
|
|
||
|
|
If table is in wrong schema, recreate it:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Drop and recreate in public schema
|
||
|
|
docker exec blockscout-postgres psql -U blockscout -d blockscout << 'SQL'
|
||
|
|
-- Drop if exists in wrong schema
|
||
|
|
DROP TABLE IF EXISTS migrations_status CASCADE;
|
||
|
|
|
||
|
|
-- Recreate in public schema (migrations will do this)
|
||
|
|
-- Or run migrations again
|
||
|
|
SQL
|
||
|
|
|
||
|
|
# Then run migrations
|
||
|
|
BLOCKSCOUT_CONTAINER=$(docker ps -a | grep blockscout | grep -v postgres | awk '{print $1}' | head -1)
|
||
|
|
docker start $BLOCKSCOUT_CONTAINER
|
||
|
|
sleep 10
|
||
|
|
docker exec -it $BLOCKSCOUT_CONTAINER bin/blockscout eval "Explorer.Release.migrate()"
|
||
|
|
```
|
||
|
|
|
||
|
|
### Solution 4: Check for Multiple Databases
|
||
|
|
|
||
|
|
Verify Blockscout is connecting to the correct database:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# List all databases
|
||
|
|
docker exec blockscout-postgres psql -U blockscout -d blockscout -c "\l"
|
||
|
|
|
||
|
|
# Check which database has the table
|
||
|
|
docker exec blockscout-postgres psql -U blockscout -d postgres -c "
|
||
|
|
SELECT datname FROM pg_database;
|
||
|
|
"
|
||
|
|
|
||
|
|
# For each database, check if migrations_status exists
|
||
|
|
for db in blockscout postgres; do
|
||
|
|
echo "Checking database: $db"
|
||
|
|
docker exec blockscout-postgres psql -U blockscout -d $db -c "
|
||
|
|
SELECT CASE WHEN EXISTS (
|
||
|
|
SELECT 1 FROM information_schema.tables
|
||
|
|
WHERE table_name = 'migrations_status'
|
||
|
|
) THEN '✅ EXISTS' ELSE '❌ MISSING' END;
|
||
|
|
"
|
||
|
|
done
|
||
|
|
```
|
||
|
|
|
||
|
|
## Most Likely Fix
|
||
|
|
|
||
|
|
The table exists but Blockscout can't see it due to schema search path. Try:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# From VMID 5000
|
||
|
|
|
||
|
|
# 1. Ensure search_path includes public
|
||
|
|
docker exec blockscout-postgres psql -U blockscout -d blockscout -c "
|
||
|
|
ALTER DATABASE blockscout SET search_path = public;
|
||
|
|
"
|
||
|
|
|
||
|
|
# 2. Verify table is accessible
|
||
|
|
docker exec blockscout-postgres psql -U blockscout -d blockscout -c "
|
||
|
|
SET search_path = public;
|
||
|
|
SELECT COUNT(*) FROM migrations_status;
|
||
|
|
"
|
||
|
|
|
||
|
|
# 3. Restart Blockscout
|
||
|
|
BLOCKSCOUT_CONTAINER=$(docker ps -a | grep blockscout | grep -v postgres | awk '{print $1}' | head -1)
|
||
|
|
docker restart $BLOCKSCOUT_CONTAINER
|
||
|
|
```
|
||
|
|
|
||
|
|
## Automated Diagnosis
|
||
|
|
|
||
|
|
Run the diagnosis script:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# From Proxmox host
|
||
|
|
cd /home/intlc/projects/proxmox/explorer-monorepo
|
||
|
|
./scripts/diagnose-blockscout-schema-issue.sh
|
||
|
|
```
|
||
|
|
|
||
|
|
This will identify:
|
||
|
|
- What schema the table is in
|
||
|
|
- What search_path is configured
|
||
|
|
- What DATABASE_URL Blockscout is using
|
||
|
|
- Whether Blockscout can actually see the table
|
||
|
|
|