Skip to content

Commit e3ab44f

Browse files
committed
Update script to generate minute replication
1 parent d1fb8c9 commit e3ab44f

File tree

2 files changed

+43
-30
lines changed

2 files changed

+43
-30
lines changed

images/replication-job/README.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,23 @@ The container requires environment variables from these files:
5858
- `POSTGRES_HOST` - PostgreSQL hostname
5959
- `POSTGRES_PORT` - PostgreSQL port (default: 5432)
6060
- `POSTGRES_DB` - Database name
61-
- `POSTGRES_USER` - Database user
61+
- `POSTGRES_USER` - Database user (must have replication and SELECT permissions)
6262
- `POSTGRES_PASSWORD` - Database password
6363
- `REPLICATION_SLOT` - Logical replication slot name (default: `osm_repl`)
6464

65+
**Important**: The database user must have the following permissions:
66+
- `REPLICATION` privilege (to read from logical replication slot)
67+
- `SELECT` permission on the `changesets` table (required by `osmdbt-create-diff`)
68+
69+
To grant these permissions, run as a database administrator:
70+
```sql
71+
-- Create user with replication privilege
72+
CREATE ROLE osmdbt_user WITH REPLICATION LOGIN PASSWORD 'your_password';
73+
74+
-- Grant SELECT on changesets table
75+
GRANT SELECT ON TABLE changesets TO osmdbt_user;
76+
```
77+
6578
#### S3 Configuration
6679
- `CLOUDPROVIDER` - Cloud provider (default: `aws`)
6780
- `AWS_S3_BUCKET` - S3 bucket name for replication files

images/replication-job/start.sh

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ workingDirectory="${WORKING_DIRECTORY:-/mnt/data}"
2121
tmpDirectory="${workingDirectory}/tmp"
2222
runDirectory="${workingDirectory}/run"
2323
changesDir="${workingDirectory}"
24+
logDirectory="${workingDirectory}/logs" # Separate directory for application logs
2425
osmdbtConfig="/osmdbt-config.yaml"
2526

2627
# Replication variables
@@ -45,11 +46,11 @@ INTEGRITY_CHECK_RETRIES=3
4546
CLEANUP_INTERVAL=300 # seconds (5 minutes)
4647

4748
# Process tracking
48-
processed_files_log="${workingDirectory}/processed_files.log"
49+
processed_files_log="${logDirectory}/processed_files.log"
4950
osmdbt_pid_file="${runDirectory}/osmdbt.pid"
5051

5152
# ---- Directory Setup ----
52-
mkdir -p "$workingDirectory" "$tmpDirectory" "$runDirectory"
53+
mkdir -p "$workingDirectory" "$tmpDirectory" "$runDirectory" "$logDirectory"
5354

5455
# ---- osmdbt-config.yaml creation ----
5556
cat <<EOF > "$osmdbtConfig"
@@ -92,7 +93,6 @@ function ensure_replication_slot_exists() {
9293

9394
local error_msg="ERROR: Failed to create replication slot '$REPLICATION_SLOT'. The '$REPLICATION_PLUGIN' plugin may not be installed."
9495
echo "$error_msg"
95-
send_slack_message "🚨 ${ENVIROMENT:-production}: $error_msg"
9696
return 1
9797
}
9898

@@ -119,7 +119,6 @@ function recover_state_file() {
119119
if aws s3 cp "$s3_state_path" "$state_file"; then
120120
echo "$(date +%F_%H:%M:%S): Successfully recovered state.txt from S3:"
121121
cat "$state_file"
122-
send_slack_message "${ENVIROMENT:-production}: Recovered state.txt from S3. Continuing replication from last known sequence."
123122
return 0
124123
else
125124
echo "$(date +%F_%H:%M:%S): WARNING: Failed to download state.txt from S3"
@@ -207,23 +206,24 @@ function upload_file_to_s3() {
207206
if ! verify_file_integrity "$local_file" "$file_type"; then
208207
local error_msg="🚨 ${ENVIROMENT:-production}: Integrity check failed for $local_file. File will not be uploaded."
209208
echo "$(date +%F_%H:%M:%S): $error_msg"
210-
send_slack_message "$error_msg"
211209
return 1
212210
fi
213211

214-
# Determine S3 path
215-
local filename=$(basename "$local_file")
216-
local s3_path="${AWS_S3_BUCKET}/${REPLICATION_FOLDER}/${filename}"
212+
# Determine S3 path preserving directory structure
213+
# Get relative path from changesDir (e.g., /mnt/data/000/871/309.osc.gz -> 000/871/309.osc.gz)
214+
local relative_path="${local_file#${changesDir}/}"
215+
# Remove leading slash if changesDir doesn't end with one
216+
relative_path="${relative_path#/}"
217+
local s3_path="${AWS_S3_BUCKET}/${REPLICATION_FOLDER}/${relative_path}"
217218

218219
echo "$(date +%F_%H:%M:%S): Uploading $local_file to S3: $s3_path"
219220

220221
if aws s3 cp "$local_file" "$s3_path" --acl public-read; then
221-
echo "$(date +%F_%H:%M:%S): Successfully uploaded $filename to S3"
222+
echo "$(date +%F_%H:%M:%S): Successfully uploaded $relative_path to S3"
222223
return 0
223224
else
224-
local error_msg="🚨 ${ENVIROMENT:-production}: Failed to upload $filename to S3"
225+
local error_msg="🚨 ${ENVIROMENT:-production}: Failed to upload $relative_path to S3"
225226
echo "$(date +%F_%H:%M:%S): $error_msg"
226-
send_slack_message "$error_msg"
227227
return 1
228228
fi
229229
}
@@ -235,9 +235,11 @@ function upload_replication_files() {
235235
local osc_file="$1"
236236
local general_state_file="${changesDir}/state.txt"
237237

238-
# Extract base name from osc file (e.g., "870.osc.gz" -> "870")
238+
# Extract base name and directory from osc file
239+
# Handle paths like /mnt/data/000/871/305.osc.gz -> /mnt/data/000/871/305.state.txt
240+
local osc_dir=$(dirname "$osc_file")
239241
local osc_basename=$(basename "$osc_file" .osc.gz)
240-
local specific_state_file="${changesDir}/${osc_basename}.state.txt"
242+
local specific_state_file="${osc_dir}/${osc_basename}.state.txt"
241243

242244
local upload_success=true
243245

@@ -312,16 +314,16 @@ function send_slack_message() {
312314
local timestamp=$(date +%F_%H:%M:%S)
313315
local full_message="[OSM Replication] $timestamp - $message"
314316

315-
# if curl -X POST -H 'Content-type: application/json' \
316-
# --data "{\"text\": \"$full_message\"}" \
317-
# "$SLACK_WEBHOOK_URL" >/dev/null 2>&1; then
318-
# echo "$(date +%F_%H:%M:%S): Slack notification sent: $message"
319-
# slack_message_count=$((slack_message_count + 1))
320-
# return 0
321-
# else
322-
# echo "$(date +%F_%H:%M:%S): WARNING: Failed to send Slack notification"
323-
# return 1
324-
# fi
317+
if curl -X POST -H 'Content-type: application/json' \
318+
--data "{\"text\": \"$full_message\"}" \
319+
"$SLACK_WEBHOOK_URL" >/dev/null 2>&1; then
320+
echo "$(date +%F_%H:%M:%S): Slack notification sent: $message"
321+
slack_message_count=$((slack_message_count + 1))
322+
return 0
323+
else
324+
echo "$(date +%F_%H:%M:%S): WARNING: Failed to send Slack notification"
325+
return 1
326+
fi
325327
}
326328

327329
# ============================================================================
@@ -336,8 +338,8 @@ function cleanup_orphaned_files() {
336338
find "$workingDirectory" -name "*.lock" -type f -mmin +10 -delete && cleaned=$((cleaned + 1))
337339
find "$runDirectory" -name "*.lock" -type f -mmin +10 -delete && cleaned=$((cleaned + 1))
338340

339-
# Remove old log files (keep only recent ones)
340-
find "$workingDirectory" -name "*.log" -type f -mtime +7 -delete && cleaned=$((cleaned + 1))
341+
# Remove old application log files (keep only recent ones)
342+
find "$logDirectory" -name "*.log" -type f -mtime +7 -delete && cleaned=$((cleaned + 1))
341343

342344
# Remove incomplete .osc.gz files (0 bytes or corrupted)
343345
while IFS= read -r -d '' file; do
@@ -410,7 +412,7 @@ function execute_replication_cycle() {
410412

411413
# Execute osmdbt-get-log
412414
echo "$(date +%F_%H:%M:%S): Running osmdbt-get-log..."
413-
if ! /osmdbt/build/src/osmdbt-get-log -c "$osmdbtConfig" 2>&1 | tee -a "${workingDirectory}/osmdbt-get-log.log"; then
415+
if ! /osmdbt/build/src/osmdbt-get-log -c "$osmdbtConfig" 2>&1 | tee -a "${logDirectory}/osmdbt-get-log.log"; then
414416
local error_msg="🚨 ${ENVIROMENT:-production}: osmdbt-get-log failed"
415417
echo "$(date +%F_%H:%M:%S): $error_msg"
416418
send_slack_message "$error_msg"
@@ -419,7 +421,7 @@ function execute_replication_cycle() {
419421

420422
# Execute osmdbt-create-diff
421423
echo "$(date +%F_%H:%M:%S): Running osmdbt-create-diff..."
422-
if ! /osmdbt/build/src/osmdbt-create-diff -c "$osmdbtConfig" 2>&1 | tee -a "${workingDirectory}/osmdbt-create-diff.log"; then
424+
if ! /osmdbt/build/src/osmdbt-create-diff -c "$osmdbtConfig" 2>&1 | tee -a "${logDirectory}/osmdbt-create-diff.log"; then
423425
local error_msg="🚨 ${ENVIROMENT:-production}: osmdbt-create-diff failed"
424426
echo "$(date +%F_%H:%M:%S): $error_msg"
425427
send_slack_message "$error_msg"
@@ -446,7 +448,6 @@ function execute_replication_cycle() {
446448
else
447449
local error_msg="🚨 ${ENVIROMENT:-production}: Failed to upload replication files for $latest_osc"
448450
echo "$(date +%F_%H:%M:%S): $error_msg"
449-
send_slack_message "$error_msg"
450451
return 1
451452
fi
452453
else
@@ -475,7 +476,6 @@ function wait_for_postgresql() {
475476

476477
local error_msg="🚨 ${ENVIROMENT:-production}: PostgreSQL is not ready after $max_attempts attempts"
477478
echo "$(date +%F_%H:%M:%S): $error_msg"
478-
send_slack_message "$error_msg"
479479
return 1
480480
}
481481

0 commit comments

Comments
 (0)