aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Alexandre Alapetite <alexandre@alapetite.fr> 2017-10-12 20:11:06 +0200
committerGravatar GitHub <noreply@github.com> 2017-10-12 20:11:06 +0200
commitf632a346269100d6a93bef318ffa66c97f16f6fa (patch)
treeaffdcac8889fcaeb04c9934a37ae6f3a5422c0ea
parent6372e51cd6a6846c11366b5b5f56409198af6e24 (diff)
CLI optimize database (#1663)
CLI optimize database https://github.com/FreshRSS/FreshRSS/issues/1583 And VACUUM in SQLite https://github.com/FreshRSS/FreshRSS/issues/918 Add VACUUM for PostgreSQL (Not tested yet)
-rw-r--r--CHANGELOG.md4
-rwxr-xr-xapp/Controllers/configureController.php6
-rwxr-xr-xapp/Controllers/entryController.php4
-rw-r--r--app/Controllers/userController.php4
-rw-r--r--app/Models/DatabaseDAO.php41
-rw-r--r--app/Models/DatabaseDAOPGSQL.php37
-rw-r--r--app/Models/DatabaseDAOSQLite.php13
-rw-r--r--app/Models/EntryDAO.php22
-rw-r--r--app/Models/EntryDAOPGSQL.php11
-rw-r--r--app/Models/EntryDAOSQLite.php8
-rw-r--r--cli/README.md3
-rwxr-xr-xcli/db-optimize.php20
-rwxr-xr-xcli/user-info.php5
13 files changed, 130 insertions, 48 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 051b04a3e..97fcdcbed 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,10 @@
* Remove "SimplePie" name from HTTP User-Agent string [#1656](https://github.com/FreshRSS/FreshRSS/pull/1656)
* Bug fixing
* Work-around for `CURLOPT_FOLLOWLOCATION` `open_basedir` bug in favicons and PubSubHubbub [#1655](https://github.com/FreshRSS/FreshRSS/issues/1655)
+* CLI
+ * New command `./cli/db-optimize.php` for database optimisation [#1583](https://github.com/FreshRSS/FreshRSS/issues/1583)
+* SQL
+ * Perform `VACUUM` on SQLite and PostgreSQL databases when optimisation is requested [#918](https://github.com/FreshRSS/FreshRSS/issues/918)
* Misc.
* Translation validation tool [#1653](https://github.com/FreshRSS/FreshRSS/pull/1653)
* Translation manipulation tool [#1658](https://github.com/FreshRSS/FreshRSS/pull/1658)
diff --git a/app/Controllers/configureController.php b/app/Controllers/configureController.php
index 155221d19..9d2ee450c 100755
--- a/app/Controllers/configureController.php
+++ b/app/Controllers/configureController.php
@@ -225,10 +225,12 @@ class FreshRSS_configure_Controller extends Minz_ActionController {
$entryDAO = FreshRSS_Factory::createEntryDao();
$this->view->nb_total = $entryDAO->count();
- $this->view->size_user = $entryDAO->size();
+
+ $databaseDAO = FreshRSS_Factory::createDatabaseDAO();
+ $this->view->size_user = $databaseDAO->size();
if (FreshRSS_Auth::hasAccess('admin')) {
- $this->view->size_total = $entryDAO->size(true);
+ $this->view->size_total = $databaseDAO->size(true);
}
}
diff --git a/app/Controllers/entryController.php b/app/Controllers/entryController.php
index c40588105..bd8b65b2b 100755
--- a/app/Controllers/entryController.php
+++ b/app/Controllers/entryController.php
@@ -147,8 +147,8 @@ class FreshRSS_entry_Controller extends Minz_ActionController {
@set_time_limit(300);
- $entryDAO = FreshRSS_Factory::createEntryDao();
- $entryDAO->optimizeTable();
+ $databaseDAO = FreshRSS_Factory::createDatabaseDAO();
+ $databaseDAO->optimize();
$feedDAO = FreshRSS_Factory::createFeedDao();
$feedDAO->updateCachedValues();
diff --git a/app/Controllers/userController.php b/app/Controllers/userController.php
index a58501186..2a1d43d9e 100644
--- a/app/Controllers/userController.php
+++ b/app/Controllers/userController.php
@@ -120,7 +120,9 @@ class FreshRSS_user_Controller extends Minz_ActionController {
// Get information about the current user.
$entryDAO = FreshRSS_Factory::createEntryDao($this->view->current_user);
$this->view->nb_articles = $entryDAO->count();
- $this->view->size_user = $entryDAO->size();
+
+ $databaseDAO = FreshRSS_Factory::createDatabaseDAO();
+ $this->view->size_user = $databaseDAO->size();
}
public static function createUser($new_user_name, $passwordPlain, $apiPasswordPlain, $userConfig = array(), $insertDefaultFeeds = true) {
diff --git a/app/Models/DatabaseDAO.php b/app/Models/DatabaseDAO.php
index 6ba5bca3e..f5469f2b7 100644
--- a/app/Models/DatabaseDAO.php
+++ b/app/Models/DatabaseDAO.php
@@ -80,4 +80,45 @@ class FreshRSS_DatabaseDAO extends Minz_ModelPdo {
return $list;
}
+
+ public function size($all = false) {
+ $db = FreshRSS_Context::$system_conf->db;
+ $sql = 'SELECT SUM(data_length + index_length) FROM information_schema.TABLES WHERE table_schema=?'; //MySQL
+ $values = array($db['base']);
+ if (!$all) {
+ $sql .= ' AND table_name LIKE ?';
+ $values[] = $this->prefix . '%';
+ }
+ $stm = $this->bd->prepare($sql);
+ $stm->execute($values);
+ $res = $stm->fetchAll(PDO::FETCH_COLUMN, 0);
+ return $res[0];
+ }
+
+ public function optimize() {
+ $ok = true;
+
+ $sql = 'OPTIMIZE TABLE `' . $this->prefix . 'entry`'; //MySQL
+ $stm = $this->bd->prepare($sql);
+ $ok &= $stm != false;
+ if ($stm) {
+ $ok &= $stm->execute();
+ }
+
+ $sql = 'OPTIMIZE TABLE `' . $this->prefix . 'feed`'; //MySQL
+ $stm = $this->bd->prepare($sql);
+ $ok &= $stm != false;
+ if ($stm) {
+ $ok &= $stm->execute();
+ }
+
+ $sql = 'OPTIMIZE TABLE `' . $this->prefix . 'category`'; //MySQL
+ $stm = $this->bd->prepare($sql);
+ $ok &= $stm != false;
+ if ($stm) {
+ $ok &= $stm->execute();
+ }
+
+ return $ok;
+ }
}
diff --git a/app/Models/DatabaseDAOPGSQL.php b/app/Models/DatabaseDAOPGSQL.php
index 2a18db970..1b3f7408d 100644
--- a/app/Models/DatabaseDAOPGSQL.php
+++ b/app/Models/DatabaseDAOPGSQL.php
@@ -40,4 +40,41 @@ class FreshRSS_DatabaseDAOPGSQL extends FreshRSS_DatabaseDAO {
'default' => $dao['default'],
);
}
+
+ public function size($all = true) {
+ $db = FreshRSS_Context::$system_conf->db;
+ $sql = 'SELECT pg_size_pretty(pg_database_size(?))';
+ $values = array($db['base']);
+ $stm = $this->bd->prepare($sql);
+ $stm->execute($values);
+ $res = $stm->fetchAll(PDO::FETCH_COLUMN, 0);
+ return $res[0];
+ }
+
+ public function optimize() {
+ $ok = true;
+
+ $sql = 'VACUUM `' . $this->prefix . 'entry`';
+ $stm = $this->bd->prepare($sql);
+ $ok &= $stm != false;
+ if ($stm) {
+ $ok &= $stm->execute();
+ }
+
+ $sql = 'VACUUM `' . $this->prefix . 'feed`';
+ $stm = $this->bd->prepare($sql);
+ $ok &= $stm != false;
+ if ($stm) {
+ $ok &= $stm->execute();
+ }
+
+ $sql = 'VACUUM `' . $this->prefix . 'category`';
+ $stm = $this->bd->prepare($sql);
+ $ok &= $stm != false;
+ if ($stm) {
+ $ok &= $stm->execute();
+ }
+
+ return $ok;
+ }
}
diff --git a/app/Models/DatabaseDAOSQLite.php b/app/Models/DatabaseDAOSQLite.php
index 2e1df132e..d3aedb3c0 100644
--- a/app/Models/DatabaseDAOSQLite.php
+++ b/app/Models/DatabaseDAOSQLite.php
@@ -45,4 +45,17 @@ class FreshRSS_DatabaseDAOSQLite extends FreshRSS_DatabaseDAO {
'default' => $dao['dflt_value'],
);
}
+
+ public function size($all = false) {
+ return @filesize(join_path(DATA_PATH, 'users', $this->current_user, 'db.sqlite'));
+ }
+
+ public function optimize() {
+ $sql = 'VACUUM';
+ $stm = $this->bd->prepare($sql);
+ if ($stm) {
+ return $stm->execute();
+ }
+ return false;
+ }
}
diff --git a/app/Models/EntryDAO.php b/app/Models/EntryDAO.php
index bebafe500..e8b6dcdae 100644
--- a/app/Models/EntryDAO.php
+++ b/app/Models/EntryDAO.php
@@ -885,28 +885,6 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable {
return array('all' => $all, 'unread' => $unread, 'read' => $all - $unread);
}
- public function optimizeTable() {
- $sql = 'OPTIMIZE TABLE `' . $this->prefix . 'entry`'; //MySQL
- $stm = $this->bd->prepare($sql);
- if ($stm) {
- return $stm->execute();
- }
- }
-
- public function size($all = false) {
- $db = FreshRSS_Context::$system_conf->db;
- $sql = 'SELECT SUM(data_length + index_length) FROM information_schema.TABLES WHERE table_schema=?'; //MySQL
- $values = array($db['base']);
- if (!$all) {
- $sql .= ' AND table_name LIKE ?';
- $values[] = $this->prefix . '%';
- }
- $stm = $this->bd->prepare($sql);
- $stm->execute($values);
- $res = $stm->fetchAll(PDO::FETCH_COLUMN, 0);
- return $res[0];
- }
-
public static function daoToEntry($dao) {
$entry = new FreshRSS_Entry(
$dao['id_feed'],
diff --git a/app/Models/EntryDAOPGSQL.php b/app/Models/EntryDAOPGSQL.php
index 405774abf..f09fe8e75 100644
--- a/app/Models/EntryDAOPGSQL.php
+++ b/app/Models/EntryDAOPGSQL.php
@@ -46,15 +46,4 @@ END $$;';
}
return $result;
}
-
- public function size($all = true) {
- $db = FreshRSS_Context::$system_conf->db;
- $sql = 'SELECT pg_size_pretty(pg_database_size(?))';
- $values = array($db['base']);
- $stm = $this->bd->prepare($sql);
- $stm->execute($values);
- $res = $stm->fetchAll(PDO::FETCH_COLUMN, 0);
- return $res[0];
- }
-
}
diff --git a/app/Models/EntryDAOSQLite.php b/app/Models/EntryDAOSQLite.php
index 8dad54322..0f57dc1ba 100644
--- a/app/Models/EntryDAOSQLite.php
+++ b/app/Models/EntryDAOSQLite.php
@@ -261,12 +261,4 @@ class FreshRSS_EntryDAOSQLite extends FreshRSS_EntryDAO {
}
return $affected;
}
-
- public function optimizeTable() {
- //TODO: Search for an equivalent in SQLite
- }
-
- public function size($all = false) {
- return @filesize(join_path(DATA_PATH, 'users', $this->current_user, 'db.sqlite'));
- }
}
diff --git a/cli/README.md b/cli/README.md
index ce1be10a7..6f907566c 100644
--- a/cli/README.md
+++ b/cli/README.md
@@ -69,6 +69,9 @@ cd /usr/share/FreshRSS
# Returns: 1) a * iff the user is admin, 2) the name of the user,
# 3) the date/time of last user action, 4) the size occupied,
# and the number of: 5) categories, 6) feeds, 7) read articles, 8) unread articles, and 9) favourites
+
+./cli/db-optimize.php --user username
+# Optimize database (reduces the size) for a given user (perform `OPTIMIZE TABLE` in MySQL, `VACUUM` in SQLite)
```
diff --git a/cli/db-optimize.php b/cli/db-optimize.php
new file mode 100755
index 000000000..83123a669
--- /dev/null
+++ b/cli/db-optimize.php
@@ -0,0 +1,20 @@
+#!/usr/bin/php
+<?php
+require('_cli.php');
+
+$options = getopt('', array(
+ 'user:',
+ ));
+
+if (empty($options['user'])) {
+ fail('Usage: ' . basename(__FILE__) . " --user username");
+}
+
+$username = cliInitUser($options['user']);
+
+echo 'FreshRSS optimizing database for user “', $username, "”…\n";
+
+$databaseDAO = FreshRSS_Factory::createDatabaseDAO($username);
+$ok = $databaseDAO->optimize();
+
+done($ok);
diff --git a/cli/user-info.php b/cli/user-info.php
index aa3e239b8..41b95cbf3 100755
--- a/cli/user-info.php
+++ b/cli/user-info.php
@@ -19,6 +19,7 @@ foreach ($users as $username) {
$catDAO = new FreshRSS_CategoryDAO();
$feedDAO = FreshRSS_Factory::createFeedDao($username);
$entryDAO = FreshRSS_Factory::createEntryDao($username);
+ $databaseDAO = FreshRSS_Factory::createDatabaseDAO($username);
$nbEntries = $entryDAO->countUnreadRead();
$nbFavorites = $entryDAO->countUnreadReadFavorites();
@@ -27,7 +28,7 @@ foreach ($users as $username) {
echo
$username, "\t",
date('c', FreshRSS_UserDAO::mtime($username)), "\t",
- format_bytes($entryDAO->size()), "\t",
+ format_bytes($databaseDAO->size()), "\t",
$catDAO->count(), " categories\t",
count($feedDAO->listFeedsIds()), " feeds\t",
$nbEntries['read'], " reads\t",
@@ -38,7 +39,7 @@ foreach ($users as $username) {
echo
$username, "\t",
FreshRSS_UserDAO::mtime($username), "\t",
- $entryDAO->size(), "\t",
+ $databaseDAO->size(), "\t",
$catDAO->count(), "\t",
count($feedDAO->listFeedsIds()), "\t",
$nbEntries['read'], "\t",