1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-22 18:50:08 +03:00

B #3269: onedb purge-done eat too much RAM (#3376)

* Process done VMs in pages, instead of all together
    * Add new method to iterate over pages
    * Add new CLI paramter to specify pages size
This commit is contained in:
Alejandro Huertas Herrero 2019-05-28 17:13:31 +02:00 committed by Ruben S. Montero
parent 2556fb2df9
commit b386ae4444
3 changed files with 52 additions and 24 deletions

View File

@ -233,10 +233,12 @@ module OpenNebula
# Gets a hash from a info page from pool
# size:: nil => default page size
# > 0 => page size
# > 0 => page size
# current first element of the page
# extended true to get extended information
# state state of the objects
# hash:: return page as a hash
def get_page(size, current, extended = false)
def get_page(size, current, extended = false, state = -1)
rc = nil
if PAGINATED_POOLS.include?(@pool_name)
@ -249,19 +251,43 @@ module OpenNebula
end
size = OpenNebula.pool_page_size if (!size || size == 0)
rc = @client.call(method, @user_id, current, -size, -1)
rc = @client.call(method, @user_id, current, -size, state)
initialize_xml(rc, @pool_name)
else
rc = info
end
return rc
return rc
end
# Iterates over pool pages
# size:: nil => default page size
# > 0 => page size
# state state of objects
# delete true to take always the first page
def each_page(size, state = -1, extended = false, delete = false)
current = 0
element = @pool_name.split('_')[0]
page = OpenNebula::XMLElement.new
loop do
page.initialize_xml(get_page(size, current, extended, state),
@pool_name)
break if page["//#{element}"].nil?
page.each("//#{element}") do |obj|
yield(obj)
end
current += size unless delete
end
end
# Return true if pool is paginated
def is_paginated?
PAGINATED_POOLS.include?(@pool_name)
PAGINATED_POOLS.include?(@pool_name)
end
end
end

View File

@ -291,6 +291,14 @@ DELETE= {
:description => "Delete all matched xpaths"
}
PAGES = {
:name => 'pages',
:short => '-p pages',
:large => '--pages pages',
:description => 'Nummber of pages to purge VMs',
:format => Integer
}
cmd=CommandParser::CmdParser.new(ARGV) do
description <<-EOT.unindent
This command enables the user to manage the OpenNebula database. It
@ -500,7 +508,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do
EOT
command :'purge-done', purge_done_desc,
:options => [START_TIME, END_TIME] do
:options => [START_TIME, END_TIME, PAGES] do
begin
action = OneDBLive.new
action.purge_done_vm(options)

View File

@ -4,7 +4,8 @@ require 'base64'
class OneDBLive
EDITOR_PATH='/bin/vi'
EDITOR_PATH = '/bin/vi'
PAGES = 0
def initialize
@client = nil
@ -206,30 +207,23 @@ class OneDBLive
end
def purge_done_vm(options = {})
vmpool = OpenNebula::VirtualMachinePool.new(client)
vmpool.info(OpenNebula::Pool::INFO_ALL,
-1,
-1,
OpenNebula::VirtualMachine::VM_STATE.index('DONE'))
ops = {
start_time: 0,
end_time: Time.now
}.merge(options)
ops = { :start_time => 0,
:end_time => Time.now,
:pages => PAGES }.merge(options)
vmpool = OpenNebula::VirtualMachinePool.new(client)
start_time = ops[:start_time].to_i
end_time = ops[:end_time].to_i
done = OpenNebula::VirtualMachine::VM_STATE.index('DONE')
last_id = vmpool["/VM_POOL/VM[last()]/ID"]
vmpool.each_page(ops[:pages], done, false, true) do |obj|
print "VM with ID: #{obj['ID']} purged \r"
vmpool.each do |vm|
print percentage_line(vm.id, last_id, true)
time = obj['ETIME'].to_i
time = vm["ETIME"].to_i
next unless time >= start_time && time < end_time
delete("vm_pool", "oid = #{vm.id}", false)
delete("history", "vid = #{vm.id}", false)
delete('vm_pool', "oid = #{obj['ID']}", false)
delete('history', "vid = #{obj['ID']}", false)
end
end