Skip to content

Commit 7e232e1

Browse files
authored
restore_logs.sh: auto detect the directory prefix
1 parent 715c54f commit 7e232e1

File tree

1 file changed

+125
-65
lines changed

1 file changed

+125
-65
lines changed

scripts/selfhost/restore_logs.sh

Lines changed: 125 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
#!/bin/bash
22

3+
# Simple logging
4+
log() {
5+
echo "[$(date '+%H:%M:%S')] $1"
6+
}
7+
8+
log_error() {
9+
echo "[$(date '+%H:%M:%S')] ERROR: $1" >&2
10+
}
11+
12+
log_step() {
13+
echo "[$(date '+%H:%M:%S')] [$1/$2] $3"
14+
}
15+
316
# Parse arguments
417
while [[ $# -gt 0 ]]; do
518
case "$1" in
@@ -16,24 +29,23 @@ while [[ $# -gt 0 ]]; do
1629
DATE_ARG="$1"
1730
shift
1831
else
19-
echo "Unknown parameter: $1"
32+
log_error "Unknown parameter: $1"
2033
exit 1
2134
fi
2235
;;
2336
esac
2437
done
2538

26-
# Check required parameters
39+
# Validate parameters
2740
if [[ -z "$STAGE" || -z "$DATE_ARG" ]]; then
28-
echo "Missing required parameters: --stage or yyyymmdd date"
41+
log_error "Missing required parameters: --stage or yyyymmdd date"
2942
exit 1
3043
fi
3144

32-
# If DSN not provided, try to get from environment variable
3345
if [[ -z "$DSN" ]]; then
3446
DSN="$BENDSQL_DSN"
3547
if [[ -z "$DSN" ]]; then
36-
echo "--dsn parameter not provided and BENDSQL_DSN environment variable not set"
48+
log_error "DSN not provided and BENDSQL_DSN not set"
3749
exit 1
3850
fi
3951
fi
@@ -43,93 +55,141 @@ YEAR=${DATE_ARG:0:4}
4355
MONTH=${DATE_ARG:4:2}
4456
DAY=${DATE_ARG:6:2}
4557
FORMATTED_DATE="${YEAR}-${MONTH}-${DAY}"
58+
TAR_FILE="data_${FORMATTED_DATE}.tar.gz"
59+
60+
log "Starting log restoration for date: ${FORMATTED_DATE}"
61+
log "Source stage: @${STAGE}, Target file: ${TAR_FILE}"
4662

47-
# 1. Get download presigned URL
48-
DOWNLOAD_SQL="PRESIGN DOWNLOAD @${STAGE}/data_${FORMATTED_DATE}.tar.gz"
63+
# Step 1: Generate download URL
64+
log_step "1" "6" "Generating presigned download URL for @${STAGE}/${TAR_FILE}"
65+
DOWNLOAD_SQL="PRESIGN DOWNLOAD @${STAGE}/${TAR_FILE}"
4966
DOWNLOAD_URL=$(bendsql --dsn "${DSN}" --query="${DOWNLOAD_SQL}" | awk '{print $3}')
5067

5168
if [[ -z "$DOWNLOAD_URL" ]]; then
52-
echo "Failed to get download URL"
69+
log_error "Failed to generate download URL for ${TAR_FILE}"
5370
exit 1
5471
fi
72+
log "Download URL generated successfully"
5573

56-
# 2. Download the file
57-
TAR_FILE="data_${FORMATTED_DATE}.tar.gz"
58-
echo "Downloading file: ${TAR_FILE}"
59-
curl -o "${TAR_FILE}" "${DOWNLOAD_URL}"
74+
# Step 2: Download backup
75+
log_step "2" "6" "Downloading ${TAR_FILE} from stage @${STAGE}"
76+
curl -s -o "${TAR_FILE}" "${DOWNLOAD_URL}"
6077

6178
if [[ ! -f "${TAR_FILE}" ]]; then
62-
echo "File download failed"
79+
log_error "Failed to download ${TAR_FILE}"
6380
exit 1
6481
fi
6582

66-
# 3. Extract the file
67-
echo "Extracting file: ${TAR_FILE}"
83+
FILE_SIZE=$(du -h "${TAR_FILE}" | cut -f1)
84+
log "Downloaded ${TAR_FILE} successfully (${FILE_SIZE})"
85+
86+
# Step 3: Extract archive
87+
log_step "3" "6" "Extracting ${TAR_FILE} to temporary directory"
6888
TEMP_DIR="temp_extracted_${DATE_ARG}"
6989
mkdir -p "${TEMP_DIR}"
7090
tar -xzf "${TAR_FILE}" -C "${TEMP_DIR}"
7191

72-
# 4. Process and upload each file
92+
EXTRACTED_FILES=$(find "${TEMP_DIR}" -type f | wc -l)
93+
log "Extracted ${EXTRACTED_FILES} files from ${TAR_FILE}"
94+
95+
# Step 4: Detect path prefix
96+
log_step "4" "6" "Analyzing directory structure for path prefix"
97+
TARGET_DIRS=("columns" "user_functions" "query_raw_logs" "query_logs" "query_profile_logs")
98+
PREFIX=""
99+
100+
for target_dir in "${TARGET_DIRS[@]}"; do
101+
SAMPLE_FILE=$(find "${TEMP_DIR}" -path "*/${target_dir}/*" -type f | head -1)
102+
if [[ -n "$SAMPLE_FILE" ]]; then
103+
RELATIVE_PATH="${SAMPLE_FILE#${TEMP_DIR}/}"
104+
PREFIX=$(echo "$RELATIVE_PATH" | sed "s|/${target_dir}/.*||" | sed "s|${target_dir}/.*||")
105+
if [[ -n "$PREFIX" ]]; then
106+
PREFIX="${PREFIX}/"
107+
fi
108+
break
109+
fi
110+
done
111+
112+
if [[ -n "$PREFIX" ]]; then
113+
log "Path prefix detected: '${PREFIX}' - will be stripped during upload"
114+
else
115+
log "No path prefix detected - using original file paths"
116+
fi
117+
118+
# Step 5: Upload files
73119
UPLOAD_STAGE="${STAGE}_${YEAR}_${MONTH}_${DAY}"
120+
log_step "5" "6" "Uploading ${EXTRACTED_FILES} files to stage @${UPLOAD_STAGE}"
121+
122+
bendsql --dsn "${DSN}" --query="DROP STAGE IF EXISTS ${UPLOAD_STAGE}" >/dev/null 2>&1
123+
bendsql --dsn "${DSN}" --query="CREATE STAGE ${UPLOAD_STAGE}" >/dev/null 2>&1
124+
log "Created destination stage: @${UPLOAD_STAGE}"
74125

75-
bendsql --dsn "${DSN}" --query="DROP STAGE IF EXISTS ${UPLOAD_STAGE}"
76-
bendsql --dsn "${DSN}" --query="CREATE STAGE ${UPLOAD_STAGE}"
126+
TOTAL_FILES=$(find "${TEMP_DIR}" -type f | wc -l)
127+
CURRENT_FILE=0
128+
UPLOAD_SUCCESS=0
129+
UPLOAD_FAILED=0
77130

78131
find "${TEMP_DIR}" -type f | while read -r FILE; do
132+
CURRENT_FILE=$((CURRENT_FILE + 1))
79133
RELATIVE_PATH="${FILE#${TEMP_DIR}/}"
80-
81-
# Get upload presigned URL
82-
UPLOAD_SQL="PRESIGN UPLOAD @${UPLOAD_STAGE}/${RELATIVE_PATH}"
83-
UPLOAD_URL=$(bendsql --dsn "${DSN}" --query="${UPLOAD_SQL}" | awk '{print $3}')
84-
85-
if [[ -z "$UPLOAD_URL" ]]; then
86-
echo "Failed to get upload URL for: ${RELATIVE_PATH}"
87-
continue
134+
135+
if [[ -n "$PREFIX" && "$RELATIVE_PATH" == ${PREFIX}* ]]; then
136+
UPLOAD_PATH="${RELATIVE_PATH#${PREFIX}}"
137+
else
138+
UPLOAD_PATH="$RELATIVE_PATH"
88139
fi
89140

90-
echo "Uploading file: ${RELATIVE_PATH}"
91-
curl -X PUT -T "${FILE}" "${UPLOAD_URL}"
141+
printf "\rUploading: %d/%d files (Success: %d, Failed: %d)" "$CURRENT_FILE" "$TOTAL_FILES" "$UPLOAD_SUCCESS" "$UPLOAD_FAILED"
92142

93-
if [[ $? -eq 0 ]]; then
94-
echo "Upload successful: ${RELATIVE_PATH}"
143+
UPLOAD_SQL="PRESIGN UPLOAD @${UPLOAD_STAGE}/${UPLOAD_PATH}"
144+
UPLOAD_URL=$(bendsql --dsn "${DSN}" --query="${UPLOAD_SQL}" | awk '{print $3}')
145+
146+
if [[ -n "$UPLOAD_URL" ]]; then
147+
if curl -s -X PUT -T "${FILE}" "${UPLOAD_URL}"; then
148+
UPLOAD_SUCCESS=$((UPLOAD_SUCCESS + 1))
149+
else
150+
UPLOAD_FAILED=$((UPLOAD_FAILED + 1))
151+
fi
95152
else
96-
echo "Upload failed: ${RELATIVE_PATH}"
153+
UPLOAD_FAILED=$((UPLOAD_FAILED + 1))
97154
fi
98155
done
99156

100-
# Cleanup temporary files
101-
echo "Cleaning up temporary files"
102-
rm -rf "${TEMP_DIR}"
103-
rm -f "${TAR_FILE}"
104-
echo "Temporary files cleanup is finished."
157+
echo # New line after progress
158+
log "Upload completed: ${UPLOAD_SUCCESS} successful, ${UPLOAD_FAILED} failed"
159+
160+
# Cleanup
161+
log "Cleaning up: removing ${TEMP_DIR} and ${TAR_FILE}"
162+
rm -rf "${TEMP_DIR}" "${TAR_FILE}"
105163

164+
# Step 6: Restore database
106165
RESTORE_DATABASE="${STAGE}_${YEAR}_${MONTH}_${DAY}"
107-
bendsql --dsn "${DSN}" --query="DROP DATABASE IF EXISTS ${RESTORE_DATABASE}"
108-
bendsql --dsn "${DSN}" --query="CREATE DATABASE ${RESTORE_DATABASE}"
109-
110-
echo "Restoring the '${RESTORE_DATABASE}.columns' table..."
111-
bendsql --dsn "${DSN}" --database "${RESTORE_DATABASE}" --query="create table columns like system.columns;"
112-
bendsql --dsn "${DSN}" --database "${RESTORE_DATABASE}" --query="COPY INTO columns FROM @${UPLOAD_STAGE}/columns;"
113-
echo "The '${RESTORE_DATABASE}.columns' table has been successfully restored"
114-
115-
echo "Restoring the '${RESTORE_DATABASE}.user_functions' table..."
116-
bendsql --dsn "${DSN}" --database "${RESTORE_DATABASE}" --query="create table user_functions like system.user_functions;"
117-
bendsql --dsn "${DSN}" --database "${RESTORE_DATABASE}" --query="COPY INTO user_functions FROM @${UPLOAD_STAGE}/user_functions;"
118-
echo "The '${RESTORE_DATABASE}.user_functions' table has been successfully restored"
119-
120-
echo "Restoring the '${RESTORE_DATABASE}.log_history' table..."
121-
bendsql --dsn "${DSN}" --database "${RESTORE_DATABASE}" --query="create table log_history like system_history.log_history;"
122-
bendsql --dsn "${DSN}" --database "${RESTORE_DATABASE}" --query="COPY INTO log_history FROM @${UPLOAD_STAGE}/query_raw_logs;"
123-
echo "The '${RESTORE_DATABASE}.log_history' table has been successfully restored"
124-
125-
echo "Restoring the '${RESTORE_DATABASE}.query_history' table..."
126-
bendsql --dsn "${DSN}" --database "${RESTORE_DATABASE}" --query="create table query_history like system_history.query_history;"
127-
bendsql --dsn "${DSN}" --database "${RESTORE_DATABASE}" --query="COPY INTO query_history FROM @${UPLOAD_STAGE}/query_logs;"
128-
echo "The '${RESTORE_DATABASE}.query_history' table has been successfully restored"
129-
130-
echo "Restoring the '${RESTORE_DATABASE}.profile_history' table..."
131-
bendsql --dsn "${DSN}" --database "${RESTORE_DATABASE}" --query="create table profile_history like system_history.profile_history;"
132-
bendsql --dsn "${DSN}" --database "${RESTORE_DATABASE}" --query="COPY INTO profile_history FROM @${UPLOAD_STAGE}/query_profile_logs;"
133-
echo "The '${RESTORE_DATABASE}.profile_history' table has been successfully restored"
134-
135-
echo "Processing completed"
166+
log_step "6" "6" "Creating database '${RESTORE_DATABASE}' and restoring tables"
167+
168+
bendsql --dsn "${DSN}" --query="DROP DATABASE IF EXISTS ${RESTORE_DATABASE}" >/dev/null 2>&1
169+
bendsql --dsn "${DSN}" --query="CREATE DATABASE ${RESTORE_DATABASE}" >/dev/null 2>&1
170+
log "Created database: ${RESTORE_DATABASE}"
171+
172+
# Restore tables
173+
declare -A TABLE_MAP=(
174+
["columns"]="system.columns:columns"
175+
["user_functions"]="system.user_functions:user_functions"
176+
["log_history"]="system_history.log_history:query_raw_logs"
177+
["query_history"]="system_history.query_history:query_logs"
178+
["profile_history"]="system_history.profile_history:query_profile_logs"
179+
)
180+
181+
for table_name in "${!TABLE_MAP[@]}"; do
182+
IFS=':' read -r source_table source_path <<< "${TABLE_MAP[$table_name]}"
183+
184+
log "Restoring table: ${RESTORE_DATABASE}.${table_name} from @${UPLOAD_STAGE}/${source_path}"
185+
186+
bendsql --dsn "${DSN}" --database "${RESTORE_DATABASE}" --query="CREATE TABLE ${table_name} LIKE ${source_table};" >/dev/null 2>&1
187+
bendsql --dsn "${DSN}" --database "${RESTORE_DATABASE}" --query="COPY INTO ${table_name} FROM @${UPLOAD_STAGE}/${source_path};" >/dev/null 2>&1
188+
189+
ROW_COUNT=$(bendsql --dsn "${DSN}" --database "${RESTORE_DATABASE}" --query="SELECT COUNT(*) FROM ${table_name};" | tail -1)
190+
log "Table ${table_name} restored: ${ROW_COUNT} rows"
191+
done
192+
193+
log "Log restoration completed successfully"
194+
log "Restored database: ${RESTORE_DATABASE}"
195+
log "Tables available: columns, user_functions, log_history, query_history, profile_history"

0 commit comments

Comments
 (0)