Merge pull request #4288 from pi-hole/new/gravity_repair

Implement fully-automated gravity database recovery method
This commit is contained in:
DL6ER 2021-12-22 21:08:01 +01:00 committed by GitHub
commit 3d3bb45a46
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -860,6 +860,49 @@ gravity_Cleanup() {
fi fi
} }
database_recovery() {
local result
local str="Checking integrity of existing gravity database"
local option="${1}"
echo -ne " ${INFO} ${str}..."
if result="$(pihole-FTL sqlite3 "${gravityDBfile}" "PRAGMA integrity_check" 2>&1)"; then
echo -e "${OVER} ${TICK} ${str} - no errors found"
str="Checking foreign keys of existing gravity database"
echo -ne " ${INFO} ${str}..."
if result="$(pihole-FTL sqlite3 "${gravityDBfile}" "PRAGMA foreign_key_check" 2>&1)"; then
echo -e "${OVER} ${TICK} ${str} - no errors found"
if [[ "${option}" != "force" ]]; then
return
fi
else
echo -e "${OVER} ${CROSS} ${str} - errors found:"
while IFS= read -r line ; do echo " - $line"; done <<< "$result"
fi
else
echo -e "${OVER} ${CROSS} ${str} - errors found:"
while IFS= read -r line ; do echo " - $line"; done <<< "$result"
fi
str="Trying to recover existing gravity database"
echo -ne " ${INFO} ${str}..."
# We have to remove any possibly existing recovery database or this will fail
rm -f "${gravityDBfile}.recovered" > /dev/null 2>&1
if result="$(pihole-FTL sqlite3 "${gravityDBfile}" ".recover" | pihole-FTL sqlite3 "${gravityDBfile}.recovered" 2>&1)"; then
echo -e "${OVER} ${TICK} ${str} - success"
mv "${gravityDBfile}" "${gravityDBfile}.old"
mv "${gravityDBfile}.recovered" "${gravityDBfile}"
echo -ne " ${INFO} ${gravityDBfile} has been recovered"
echo -ne " ${INFO} The old ${gravityDBfile} has been moved to ${gravityDBfile}.old"
else
echo -e "${OVER} ${CROSS} ${str} - the following errors happened:"
while IFS= read -r line ; do echo " - $line"; done <<< "$result"
echo -e " ${CROSS} Recovery failed. Try \"pihole -r recreate\" instead."
exit 1
fi
echo ""
}
helpFunc() { helpFunc() {
echo "Usage: pihole -g echo "Usage: pihole -g
Update domains from blocklists specified in adlists.list Update domains from blocklists specified in adlists.list
@ -870,10 +913,37 @@ Options:
exit 0 exit 0
} }
repairSelector() {
case "$1" in
"recover") recover_database=true;;
"recreate") recreate_database=true;;
*) echo "Usage: pihole -g -r {recover,recreate}
Attempt to repair gravity database
Available options:
pihole -g -r recover Try to recover a damaged gravity database file.
Pi-hole tries to restore as much as possible
from a corrupted gravity database.
pihole -g -r recover force Pi-hole will run the recovery process even when
no damage is detected. This option is meant to be
a last resort. Recovery is a fragile task
consuming a lot of resources and shouldn't be
performed unnecessarily.
pihole -g -r recreate Create a new gravity database file from scratch.
This will remove your existing gravity database
and create a new file from scratch. If you still
have the migration backup created when migrating
to Pi-hole v5.0, Pi-hole will import these files."
exit 0;;
esac
}
for var in "$@"; do for var in "$@"; do
case "${var}" in case "${var}" in
"-f" | "--force" ) forceDelete=true;; "-f" | "--force" ) forceDelete=true;;
"-r" | "--recreate" ) recreate_database=true;; "-r" | "--repair" ) repairSelector "$3";;
"-h" | "--help" ) helpFunc;; "-h" | "--help" ) helpFunc;;
esac esac
done done
@ -887,7 +957,7 @@ fi
gravity_Trap gravity_Trap
if [[ "${recreate_database:-}" == true ]]; then if [[ "${recreate_database:-}" == true ]]; then
str="Restoring from migration backup" str="Recreating gravity database from migration backup"
echo -ne "${INFO} ${str}..." echo -ne "${INFO} ${str}..."
rm "${gravityDBfile}" rm "${gravityDBfile}"
pushd "${piholeDir}" > /dev/null || exit pushd "${piholeDir}" > /dev/null || exit
@ -896,6 +966,10 @@ if [[ "${recreate_database:-}" == true ]]; then
echo -e "${OVER} ${TICK} ${str}" echo -e "${OVER} ${TICK} ${str}"
fi fi
if [[ "${recover_database:-}" == true ]]; then
database_recovery "$4"
fi
# Move possibly existing legacy files to the gravity database # Move possibly existing legacy files to the gravity database
if ! migrate_to_database; then if ! migrate_to_database; then
echo -e " ${CROSS} Unable to migrate to database. Please contact support." echo -e " ${CROSS} Unable to migrate to database. Please contact support."