Skip to content

Commit

Permalink
[FIX] service, web: memory error on large DB
Browse files Browse the repository at this point in the history
Fixes MemoryError when restoring large database archive.

Closes odoo#17663
opw-788273
  • Loading branch information
Jerther authored and nim-odoo committed Jan 12, 2018
1 parent d080f8c commit e546d51
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 3 deletions.
9 changes: 7 additions & 2 deletions addons/web/controllers/main.py
Expand Up @@ -17,6 +17,7 @@
import os
import re
import sys
import tempfile
import time
import werkzeug.utils
import werkzeug.wrappers
Expand All @@ -37,6 +38,7 @@
serialize_exception as _serialize_exception
from odoo.exceptions import AccessError, UserError
from odoo.models import check_method_name
from odoo.service import db

_logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -702,12 +704,15 @@ def backup(self, master_pwd, name, backup_format = 'zip'):
@http.route('/web/database/restore', type='http', auth="none", methods=['POST'], csrf=False)
def restore(self, master_pwd, backup_file, name, copy=False):
try:
data = base64.b64encode(backup_file.read())
dispatch_rpc('db', 'restore', [master_pwd, name, data, str2bool(copy)])
with tempfile.NamedTemporaryFile(delete=False) as data_file:
backup_file.save(data_file)
db.restore_db(name, data_file.name, str2bool(copy))
return http.local_redirect('/web/database/manager')
except Exception, e:
error = "Database restore error: %s" % (str(e) or repr(e))
return self._render_template(error=error)
finally:
os.unlink(data_file.name)

@http.route('/web/database/change_password', type='http', auth="none", methods=['POST'], csrf=False)
def change_password(self, master_pwd, master_pwd_new):
Expand Down
6 changes: 5 additions & 1 deletion odoo/service/db.py
Expand Up @@ -211,9 +211,13 @@ def dump_db(db_name, stream, backup_format='zip'):
return stdout

def exp_restore(db_name, data, copy=False):
def chunks(d, n=8192):
for i in range(0, len(d), n):
yield d[i:i+n]
data_file = tempfile.NamedTemporaryFile(delete=False)
try:
data_file.write(data.decode('base64'))
for chunk in chunks(data):
data_file.write(chunk.decode('base64'))
data_file.close()
restore_db(db_name, data_file.name, copy=copy)
finally:
Expand Down

0 comments on commit e546d51

Please sign in to comment.