SlideShare a Scribd company logo
1 of 44
Download to read offline
Olivier Dony
T @odony
Performance
with high
volumes
OpenERP can handle large
volumes of transactions and
large volumes of data
out of the box!
For example, each OpenERP
Online Server hosts 1000+
databases without
breaking a sweat!
Many on-site customers have
single server deployments
with millions of rows:
partners, emails, attachments,
journal items, stock moves,
workflow items, …
What if performance is an issue?
Get the right facts.
Use the right tools.
t @odony
Agenda
● Architecture / Deployment / Sizing
● Measuring & Analyzing
● Common Problems
● Anti-patterns
t @odony
OpenERP Architecture
PostgreSQL is the real
workhorse behind OpenERP,
and it scales very well!
t @odony
OpenERP Cron Worker
Deployment Architecture: single server, multi-process
Rule of thumb:
--workers=$((1+${CORES}*2))
OpenERP HTTP Worker
OpenERP HTTP Worker
OpenERP HTTP Worker
OpenERP HTTP Worker
PostgreSQL
Requests
t @odony
OpenERP Cron Worker
Deployment Architecture: multi-server, multi-process
OpenERP HTTP Worker
OpenERP HTTP Worker
OpenERP HTTP Worker
OpenERP HTTP Worker
PostgreSQL
Requests
Server 3
Load
Balancer
OpenERP Cron Worker
OpenERP HTTP Worker
OpenERP HTTP Worker
OpenERP HTTP Worker
OpenERP HTTP Worker
Server 2
Server 1
t @odony
Hardware Sizing
● Typical modern server machine
● 4/8/12 2+GHz cores
● 8-64 GB RAM
● Fast SATA/SAS/SSD disks
● Up to 100-200 active users (multi-process)
● Up to dozens of HTTP requests per second
● Up to 1000 “light” users (average SaaS user)
● For official OpenERP 7.0 deployments with no
customizations, and typical usage!
For anything else, always
perform proper load testing
before going live in production!
Then size accordingly...
t @odony
PostgreSQL Deployment tips
● Avoid deploying PostgreSQL on a VM
● If you must do it, fine-tune the VM for I/O!
● And always check out the basic PostgreSQL
performance tuning, it's conservative by
default
http://wiki.postgresql.org/wiki/Tuning_Your_PostgreSQL_Server
t @odony
Agenda
● Architecture / Deployment / Sizing
● Measuring & Analyzing
● Common Problems
● Anti-patterns
t @odony
Monitor application response times
●
You can't manage/improve what you can't
measure
●
Setup an automated monitoring of performance
and response time... even if you have no
performance problem!
●
Suggested tool: munin
●
Run OpenERP with –log-level=debug_rpc in prod!
2013-07-03 00:12:29,846 9663 DEBUG test openerp.netsvc.rpc.request:
object.execute_kw time:0.031s mem: 763716k -> 763716k (diff: 0k)('test', 1,
'*', 'sale.order', 'read', (...), {...})
t @odony
#!/bin/sh
#%# family=manual
#%# capabilities=autoconf suggest
case $1 in
autoconf)
exit 0
;;
suggest)
exit 0
;;
config)
echo graph_category openerp
echo graph_title openerp rpc request count
echo graph_vlabel num requests/minute in last 5 minutes
echo requests.label num requests
exit 0
;;
esac
# watch out for the time zone of the logs => using date -u for UTC timestamps
result=$(tail -60000 /var/log/openerp.log | grep "object.execute_kw time" | awk "BEGIN{count=0} ($1 " " 
$2) >= "`date +'%F %H:%M:%S' -ud '5 min ago'`" { count+=1; } END{print count/5}")
echo "requests.value ${result}"
exit 0
Munin plugin: OpenERP requests/minute
t @odony
#!/bin/sh
#%# family=manual
#%# capabilities=autoconf suggest
case $1 in
config)
echo graph_category openerp
echo graph_title openerp rpc requests min/average response time
echo graph_vlabel seconds
echo graph_args --units-exponent -3
echo min.label min
echo min.warning 1
echo min.critical 5
echo avg.label average
echo avg.warning 1
echo avg.critical 5
exit 0
;;
esac
# watch out for the time zone of the logs => using date -u for UTC timestamps
result=$(tail -60000 /var/log/openerp.log | grep "object.execute_kw time" | awk "BEGIN{sum=0;count=0} (
$1 " " $2) >= "`date +'%F %H:%M:%S' -ud '5 min ago'`" {split($8,t,":");time=0+t[2];if (min=="") { min=time};
sum += time; count+=1; min=(time>min)?min:time } END{print min, sum/count}")
echo -n "min.value "
echo ${result} | cut -d" " -f1
echo -n "avg.value "
echo ${result} | cut -d" " -f2
exit 0
Munin plugin: OpenERP min/avg response time
t @odony
#!/bin/sh
#%# family=manual
#%# capabilities=autoconf suggest
case $1 in
config)
echo graph_category openerp
echo graph_title openerp rpc requests max response time
echo graph_vlabel seconds
echo graph_args --units-exponent -3
echo max.label max
echo max.warning 1
echo max.critical 5
exit 0
;;..
esac
# watch out for the time zone of the logs => using date -u for UTC timestamps....
result=$(tail -60000 /var/log/openerp.log | grep "object.execute_kw time" | awk "BEGIN{sum=0;count=0} (
$1 " " $2) >= "`date +'%F %H:%M:%S' -ud '85 min ago'`" {split($8,t,":");time=0+t[2]; sum += time; count+=1;
max=(time<max)?max:time } END{print max}")
echo "max.value ${result}"
exit 0
Munin plugin: OpenERP max response time
t @odony
Monitor PostgreSQL
● postgresql.conf
● log_min_duration_statement = 50
● Set to 50 or 100 in production
● Set to 0 to log all queries and execution times for a while
● Instagram gist to capture sample + analyze
● Analyze with pgBadger or pgFouine
●
lc_messages = 'C'
t @odony
PostgreSQL Analysis
● Important PG statistic tables
● pg_stat_activity: near real-time view of transactions
● pg_locks: real-time view of existing locks
● pg_stat_user_tables: generic usage stats for all tables
● pg_statio_user_tables: generic I/O stats for all tables
t @odony
PostgreSQL Analysis: longest tables
# SELECT schemaname || '.' || relname as table,n_live_tup as num_rows
FROM pg_stat_user_tables
ORDER BY n_live_tup DESC limit 10;
┌──────────────────────────────────────────┬──────────┐
│ table │ num_rows │
├──────────────────────────────────────────┼──────────┤
│ public.stock_move │ 179544 │
│ public.ir_translation │ 134039 │
│ public.wkf_workitem │ 97195 │
│ public.wkf_instance │ 96973 │
│ public.procurement_order │ 83077 │
│ public.ir_property │ 69011 │
│ public.ir_model_data │ 59532 │
│ public.stock_move_history_ids │ 58942 │
│ public.mrp_production_move_ids │ 49714 │
│ public.mrp_bom │ 46258 │
└──────────────────────────────────────────┴──────────┘
t @odony
PostgreSQL Analysis: biggest tables
# SELECT nspname || '.' || relname AS "table",
pg_size_pretty(pg_total_relation_size(C.oid)) AS "total_size"
FROM pg_class C
LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
WHERE nspname NOT IN ('pg_catalog', 'information_schema')
AND C.relkind <> 'i'
AND nspname !~ '^pg_toast'
ORDER BY pg_total_relation_size(C.oid) DESC
LIMIT 10;
┌──────────────────────────────────────────┬────────────┐
│ table │ total_size │
├──────────────────────────────────────────┼────────────┤
│ public.stock_move │ 525 MB │
│ public.wkf_workitem │ 111 MB │
│ public.procurement_order │ 80 MB │
│ public.stock_location │ 63 MB │
│ public.ir_translation │ 42 MB │
│ public.wkf_instance │ 37 MB │
│ public.ir_model_data │ 36 MB │
│ public.ir_property │ 26 MB │
│ public.ir_attachment │ 14 MB │
│ public.mrp_bom │ 13 MB │
└──────────────────────────────────────────┴────────────┘
t @odony
PostgreSQL Analysis: biggest tables
●
Consider using the file storage for the
ir.attachment table
●
Avoid storing files in the database
●
Greatly reduces the time needed for DB backups
and backup
●
Very easy to rsync backups of DB dumps +
filestore
●
For 7.0 this setting is explained in this FAQ
t @odony
PostgreSQL Analysis: most read tables
# SELECT schemaname || '.' || relname as table, heap_blks_read as disk_reads,
heap_blks_hit as cache_reads,
heap_blks_read + heap_blks_hit as total_reads
from pg_statio_user_tables
order by heap_blks_read + heap_blks_hit desc limit 15;
┌───────────────────────────────┬────────────┬─────────────┬─────────────┐
│ table │ disk_reads │ cache_reads │ total_reads │
├───────────────────────────────┼────────────┼─────────────┼─────────────┤
│ public.stock_location │ 53796 │ 60926676388 │ 60926730184 │
│ public.stock_move │ 208763 │ 9880525282 │ 9880734045 │
│ public.stock_picking │ 15772 │ 4659569791 │ 4659585563 │
│ public.procurement_order │ 156139 │ 1430660775 │ 1430816914 │
│ public.stock_tracking │ 2621 │ 525023173 │ 525025794 │
│ public.product_product │ 11178 │ 225774346 │ 225785524 │
│ public.mrp_bom │ 27198 │ 225329643 │ 225356841 │
│ public.ir_model_fields │ 1632 │ 203361139 │ 203362771 │
│ public.stock_production_lot │ 5918 │ 127915614 │ 127921532 │
│ public.res_users │ 416 │ 115506586 │ 115507002 │
│ public.ir_model_access │ 6382 │ 104686364 │ 104692746 │
│ public.mrp_production │ 20829 │ 101523983 │ 101544812 │
│ public.product_template │ 4566 │ 76074699 │ 76079265 │
│ public.product_uom │ 18 │ 70521126 │ 70521144 │
│ public.wkf_workitem │ 129166 │ 67782919 │ 67912085 │
└───────────────────────────────┴────────────┴─────────────┴─────────────┘
t @odony
PostgreSQL Analysis: most updated/inserted/...
# SELECT schemaname || '.' || relname as table,
seq_scan,idx_scan,idx_tup_fetch+seq_tup_read lines_read_total, n_tup_ins as
num_insert,n_tup_upd as num_update,n_tup_del as num_delete
from pg_stat_user_tables order by n_tup_upd desc limit 10;
┌────────────────────────────────────┬──────────┬────────────┬──────────────────┬────────────┬────────────┬────────────┐
│ table │ seq_scan │ idx_scan │ lines_read_total │ num_insert │ num_update │ num_delete │
├────────────────────────────────────┼──────────┼────────────┼──────────────────┼────────────┼────────────┼────────────┤
│ public.stock_move │ 1188095 │ 1104711719 │ 132030135782 │ 208507 │ 9556574 │ 67298 │
│ public.procurement_order │ 226774 │ 22134417 │ 11794090805 │ 92064 │ 6882666 │ 27543 │
│ public.wkf_workitem │ 373 │ 17340039 │ 29910699 │ 1958392 │ 3280141 │ 1883794 │
│ public.stock_location │ 41402098 │ 166316501 │ 516216409246 │ 97 │ 2215107 │ 205 │
│ public.stock_picking │ 297984 │ 71732467 │ 5671488265 │ 9008 │ 1000966 │ 1954 │
│ public.stock_production_lot │ 190934 │ 28038527 │ 1124560295 │ 4318 │ 722053 │ 0 │
│ public.mrp_production │ 270568 │ 13550371 │ 476534514 │ 3816 │ 495776 │ 1883 │
│ public.sale_order_line │ 30161 │ 4757426 │ 60019207 │ 2077 │ 479752 │ 320 │
│ public.stock_tracking │ 656404 │ 97874788 │ 5054452666 │ 5914 │ 404469 │ 0 │
│ public.ir_cron │ 246636 │ 818 │ 2467441 │ 0 │ 169904 │ 0 │
└────────────────────────────────────┴──────────┴────────────┴──────────────────┴────────────┴────────────┴────────────┘
t @odony
Useful VIEW to watch locked queries
-- For PostgreSQL 9.1
CREATE VIEW monitor_blocked_queries AS
SELECT
pg_class.relname,
waiter.pid as blocked_pid,
substr(wait_act.current_query,1,30) as blocked_statement,
age(now(),wait_act.query_start) as blocked_duration,
holder.pid as blocking_pid,
substr(hold_act.current_query,1,30) as blocking_statement,
age(now(),hold_act.query_start) as blocking_duration,
waiter.transactionid as xid,
waiter.mode as wmode,
waiter.virtualtransaction as wvxid,
holder.mode as hmode,
holder.virtualtransaction as hvxid
FROM pg_locks holder join pg_locks waiter on (
holder.locktype = waiter.locktype and (
holder.database, holder.relation,
holder.page, holder.tuple,
holder.virtualxid,
holder.transactionid, holder.classid,
holder.objid, holder.objsubid
) IS NOT DISTINCT from (
waiter.database, waiter.relation,
waiter.page, waiter.tuple,
waiter.virtualxid,
waiter.transactionid, waiter.classid,
waiter.objid, waiter.objsubid
))
JOIN pg_stat_activity hold_act ON (holder.pid=hold_act.procpid)
JOIN pg_stat_activity wait_act ON (waiter.pid=wait_act.procpid)
LEFT JOIN pg_class ON (holder.relation = pg_class.oid)
WHERE
wait_act.datname = 'eurogerm' AND
holder.granted AND NOT waiter.granted
ORDER BY blocked_duration DESC;
t @odony
Useful VIEW to watch locked queries
# SELECT * FROM blocked_queries;
relname | blocked_pid | blocked_statement | blocked_duration | blocking_pid | blocking_statement
---------+-------------+--------------------------------+------------------+--------------+-------------------------
| 16504 | update "stock_tracking" set "s | 00:00:57.588357 | 16338 | <IDLE> in transaction
| 16501 | update "stock_tracking" set "f | 00:00:55.144373 | 16504 | update "stock_tracking"
(2 lignes)
... | blocking_statement | blocking_duration | xid | wmode | hmode |
... +--------------------------------+-------------------+----------+-----------+---------------|
... | <IDLE> in transaction | -00:00:00.004754 | 12630740 | ShareLock | ExclusiveLock |
... | update "stock_tracking" set "s | 00:00:57.588357 | 12630722 | ShareLock | ExclusiveLock |
t @odony
Useful tool for watching activity: pg_activity
top-like command-line utility to watch queries: running,
blocking, waiting
→ pip install pg_activity
Thanks to @cmorisse for this pointer! :-)
t @odony
Useful VIEW to watch Locks per transaction
# – For PostgreSQL 9.1
# CREATE VIEW monitor_locks AS
SELECT pg_stat_activity.procpid, pg_class.relname, pg_locks.locktype,
pg_locks.transactionid, pg_locks.virtualxid,
pg_locks.virtualtransaction, pg_locks.mode, pg_locks.granted,
pg_stat_activity.usename,
substr(pg_stat_activity.current_query,1,30) AS query,
pg_stat_activity.query_start, age(now(),pg_stat_activity.query_start)
AS duration
FROM pg_stat_activity, pg_locks
LEFT JOIN pg_class ON pg_locks.relation = pg_class.oid
WHERE pg_locks.pid = pg_stat_activity.procpid AND
pg_stat_activity.procpid != pg_backend_pid()
ORDER BY pg_stat_activity.procpid, pg_locks.granted, pg_class.relname;
t @odony
Useful VIEW to watch Locks per transaction
pid | relname | locktype | xid | virtualxid
------+-----------------------------------------------------------+------------------+----------+-----------
8597 | | transactionid | 12171567 | 11/164037
8597 | purchase_order_line_pkey | relation | | 11/164037
8597 | stock_location_location_id_index | relation | | 11/164037
8597 | stock_move_production_id_index | relation | | 11/164037
8597 | stock_move_production_id_index | relation | | 11/164037
8597 | stock_move_location_id_location_dest_id_product_id_state | relation | | 11/164037
8597 | multi_company_default | relation | | 11/164037
8597 | stock_picking_invoice_state_index | relation | | 11/164037
8597 | ir_model_access_group_id_index | relation | | 11/164037
8597 | purchase_order_line_date_planned_index | relation | | 11/164037
8597 | purchase_order_pkey | relation | | 11/164037
8597 | res_company | relation | | 11/164037
8597 | purchase_order_name_index | relation | | 11/164037
8597 | res_company | relation | | 11/164037
8597 | ir_sequence_pkey | relation | | 11/164037
8597 | ir_sequence_pkey | relation | | 11/164037
8597 | res_partner_company_id_index | relation | | 11/164037
8597 | product_product_have_pqcd_cde_index | relation | | 11/164037
8597 | stock_tracking | relation | | 11/164037
8597 | ir_translation_src_hash_idx | relation | | 11/164037
8597 | res_users | relation | | 11/164037
8597 | product_template_name_index | relation | | 11/164037
8597 | res_users | relation | | 11/164037
8597 | stock_move_tracking
t @odony
Useful VIEW to watch Locks per transaction
| mode | granted | query | query_start | duration |
+------------------+---------+--------------------------------+-------------------------------+------------------+
| AccessShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 |
| AccessShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 |
| AccessShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 |
| AccessShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 |
| RowExclusiveLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 |
| AccessShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 |
| AccessShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 |
| AccessShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 |
| AccessShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 |
| AccessShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 |
| AccessShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 |
| AccessShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 |
| AccessShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 |
| RowShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 |
| AccessShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 |
| RowExclusiveLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 |
| AccessShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 |
| AccessShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 |
| AccessShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 |
| AccessShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 |
| RowShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 |
| AccessShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 |
| AccessShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 |
t @odony
Normal Values?
● Most RPC requests should be under 200ms
● Most SQL queries should be under 100ms
● One transaction = 100-300 heavyweight locks
Find your own normal values via monitoring!
t @odony
Agenda
● Architecture / Deployment / Sizing
● Measuring & Analyzing
● Common Problems
● Anti-patterns
t @odony
Common Problems
● Stored functions
● Slow Queries/Views, Suboptimal domains
● Lock contention
● Custom locking mechanisms (queues, locks,...)
t @odony
Common Problems: Stored Functions
● Stored functional fields are triggers
● Store triggers can be:
●
store = { 'trigger_model': (mapping_function,
['trigger_field1', 'trigger_field2'],
priority) }
● store=True meaning:
self._name (lambda s,c,u,ids,c: ids, None, 10)}→
● Can be very expensive with wrong parameters or
slow functions
t @odony
Common Problems: Slow Queries
●
All SQL queries 500ms+ should be analyzed
●
Use EXPLAIN ANALYZE to examine/measure you custom
SQL queries and VIEWs
●
Try to remove parts of the query until it's fast, then fix it
●
Check cardinality of big JOINs
●
Default domain evaluation strategy
●
search([('picking_id.move_ids.partner_id', '!=', False)])
●
Implemented by combining “id IN (….)” parts
●
Have a look at _auto_join in OpenERP 7.0
'move_ids': fields.one2many('stock.move', 'picking_id',
string='Moves', _auto_join=True)
t @odony
Common Problems: Slow Queries
● No premature optimization: don't write SQL,
use the ORM always during initial
development
● If you detect a hot spot with load-tests,
consider rewriting the inefficient parts in SQL
● But:
● Make sure you're not bypassing security mechanisms
● Don't create SQL injection vectors use query parameters,→
don't concatenate user input in your SQL strings.
t @odony
Common Problems: Lock Contention
●
PostgreSQL guarantees transactional data integrity by
taking heavy-weight locks → monitor_locks
●
Updating a record blocks all FK locks on it until the
transaction is completed!
●
This will change with PostgreSQL 9.3 :-)
●
This is independent from the transaction isolation level
(Repeatable Read/Serializable/...)
→ Don't have long-running transactions!
→ Avoid updating “master data” resources in them!
(user, company, stock location, product, …)
t @odony
Common Problems: Custom Locking
●
Any kind of manual locking/queuing mechanism
is dangerous, especially in Python
●
Python locks can cause deadlocks that cannot
be detected and broken by the system!
●
Avoid it, and if you must, use the database as
lock
●
That's what scheduled jobs (ir.cron) do:
●
SELECT FOR UPDATE on the cron job row
●
→ Automatic cleanup/release
●
→ Scales well and works in multi-process!
t @odony
Agenda
● Architecture / Deployment / Sizing
● Measuring & Analyzing
● Common Problems
● Anti-patterns
t @odony
Avoid Anti-Patterns: Master the framework!
●
Make sure you really understand the browse()
mechanisms!
●
Make sure you properly use the batch API
●
Don't write SQL unless you have to, e.g for:
●
Analysis views
●
Hot spot functions, name_search(), computed_fields(), ...
t @odony
Anti-Patterns: what's wrong?
browse() must be used on lists to benefit from its optimizations!
t @odony
Anti-Patterns: what's wrong now?
browse() use is OK now, but the related field is dangerous
and costly, going through a possibly very large o2m just to find
a single product ID
t @odony
Anti-Patterns: what's wrong here?
The trigger on stock.move is for all fields which means it will
trigger for each change, while we only care about tracking_id
here

More Related Content

What's hot

Odoo Online platform: architecture and challenges
Odoo Online platform: architecture and challengesOdoo Online platform: architecture and challenges
Odoo Online platform: architecture and challengesOdoo
 
Security: Odoo Code Hardening
Security: Odoo Code HardeningSecurity: Odoo Code Hardening
Security: Odoo Code HardeningOdoo
 
Impact of the New ORM on Your Modules
Impact of the New ORM on Your ModulesImpact of the New ORM on Your Modules
Impact of the New ORM on Your ModulesOdoo
 
Odoo Experience 2018 - Code Profiling in Odoo
Odoo Experience 2018 - Code Profiling in OdooOdoo Experience 2018 - Code Profiling in Odoo
Odoo Experience 2018 - Code Profiling in OdooElínAnna Jónasdóttir
 
How does PostgreSQL work with disks: a DBA's checklist in detail. PGConf.US 2015
How does PostgreSQL work with disks: a DBA's checklist in detail. PGConf.US 2015How does PostgreSQL work with disks: a DBA's checklist in detail. PGConf.US 2015
How does PostgreSQL work with disks: a DBA's checklist in detail. PGConf.US 2015PostgreSQL-Consulting
 
An in Depth Journey into Odoo's ORM
An in Depth Journey into Odoo's ORMAn in Depth Journey into Odoo's ORM
An in Depth Journey into Odoo's ORMOdoo
 
PostgreSQL High Availability in a Containerized World
PostgreSQL High Availability in a Containerized WorldPostgreSQL High Availability in a Containerized World
PostgreSQL High Availability in a Containerized WorldJignesh Shah
 
PostgreSQL Administration for System Administrators
PostgreSQL Administration for System AdministratorsPostgreSQL Administration for System Administrators
PostgreSQL Administration for System AdministratorsCommand Prompt., Inc
 
OpenERP Performance Benchmark
OpenERP Performance BenchmarkOpenERP Performance Benchmark
OpenERP Performance BenchmarkAudaxis
 
Webinar: PostgreSQL continuous backup and PITR with Barman
Webinar: PostgreSQL continuous backup and PITR with BarmanWebinar: PostgreSQL continuous backup and PITR with Barman
Webinar: PostgreSQL continuous backup and PITR with BarmanGabriele Bartolini
 
Deep dive into PostgreSQL statistics.
Deep dive into PostgreSQL statistics.Deep dive into PostgreSQL statistics.
Deep dive into PostgreSQL statistics.Alexey Lesovsky
 
MySQL Timeout Variables Explained
MySQL Timeout Variables Explained MySQL Timeout Variables Explained
MySQL Timeout Variables Explained Mydbops
 
[pgday.Seoul 2022] POSTGRES 테스트코드로 기여하기 - 이동욱
[pgday.Seoul 2022] POSTGRES 테스트코드로 기여하기 - 이동욱[pgday.Seoul 2022] POSTGRES 테스트코드로 기여하기 - 이동욱
[pgday.Seoul 2022] POSTGRES 테스트코드로 기여하기 - 이동욱PgDay.Seoul
 
Top 10 Mistakes When Migrating From Oracle to PostgreSQL
Top 10 Mistakes When Migrating From Oracle to PostgreSQLTop 10 Mistakes When Migrating From Oracle to PostgreSQL
Top 10 Mistakes When Migrating From Oracle to PostgreSQLJim Mlodgenski
 
ClickHouse Data Warehouse 101: The First Billion Rows, by Alexander Zaitsev a...
ClickHouse Data Warehouse 101: The First Billion Rows, by Alexander Zaitsev a...ClickHouse Data Warehouse 101: The First Billion Rows, by Alexander Zaitsev a...
ClickHouse Data Warehouse 101: The First Billion Rows, by Alexander Zaitsev a...Altinity Ltd
 
OpenGurukul : Database : PostgreSQL
OpenGurukul : Database : PostgreSQLOpenGurukul : Database : PostgreSQL
OpenGurukul : Database : PostgreSQLOpen Gurukul
 
ClickHouse materialized views - a secret weapon for high performance analytic...
ClickHouse materialized views - a secret weapon for high performance analytic...ClickHouse materialized views - a secret weapon for high performance analytic...
ClickHouse materialized views - a secret weapon for high performance analytic...Altinity Ltd
 
Ceph: Open Source Storage Software Optimizations on Intel® Architecture for C...
Ceph: Open Source Storage Software Optimizations on Intel® Architecture for C...Ceph: Open Source Storage Software Optimizations on Intel® Architecture for C...
Ceph: Open Source Storage Software Optimizations on Intel® Architecture for C...Odinot Stanislas
 
Patroni - HA PostgreSQL made easy
Patroni - HA PostgreSQL made easyPatroni - HA PostgreSQL made easy
Patroni - HA PostgreSQL made easyAlexander Kukushkin
 

What's hot (20)

Odoo Online platform: architecture and challenges
Odoo Online platform: architecture and challengesOdoo Online platform: architecture and challenges
Odoo Online platform: architecture and challenges
 
Security: Odoo Code Hardening
Security: Odoo Code HardeningSecurity: Odoo Code Hardening
Security: Odoo Code Hardening
 
Impact of the New ORM on Your Modules
Impact of the New ORM on Your ModulesImpact of the New ORM on Your Modules
Impact of the New ORM on Your Modules
 
Odoo Experience 2018 - Code Profiling in Odoo
Odoo Experience 2018 - Code Profiling in OdooOdoo Experience 2018 - Code Profiling in Odoo
Odoo Experience 2018 - Code Profiling in Odoo
 
How does PostgreSQL work with disks: a DBA's checklist in detail. PGConf.US 2015
How does PostgreSQL work with disks: a DBA's checklist in detail. PGConf.US 2015How does PostgreSQL work with disks: a DBA's checklist in detail. PGConf.US 2015
How does PostgreSQL work with disks: a DBA's checklist in detail. PGConf.US 2015
 
An in Depth Journey into Odoo's ORM
An in Depth Journey into Odoo's ORMAn in Depth Journey into Odoo's ORM
An in Depth Journey into Odoo's ORM
 
PostgreSQL High Availability in a Containerized World
PostgreSQL High Availability in a Containerized WorldPostgreSQL High Availability in a Containerized World
PostgreSQL High Availability in a Containerized World
 
PostgreSQL Administration for System Administrators
PostgreSQL Administration for System AdministratorsPostgreSQL Administration for System Administrators
PostgreSQL Administration for System Administrators
 
OpenERP Performance Benchmark
OpenERP Performance BenchmarkOpenERP Performance Benchmark
OpenERP Performance Benchmark
 
Webinar: PostgreSQL continuous backup and PITR with Barman
Webinar: PostgreSQL continuous backup and PITR with BarmanWebinar: PostgreSQL continuous backup and PITR with Barman
Webinar: PostgreSQL continuous backup and PITR with Barman
 
Deep dive into PostgreSQL statistics.
Deep dive into PostgreSQL statistics.Deep dive into PostgreSQL statistics.
Deep dive into PostgreSQL statistics.
 
MySQL Timeout Variables Explained
MySQL Timeout Variables Explained MySQL Timeout Variables Explained
MySQL Timeout Variables Explained
 
[pgday.Seoul 2022] POSTGRES 테스트코드로 기여하기 - 이동욱
[pgday.Seoul 2022] POSTGRES 테스트코드로 기여하기 - 이동욱[pgday.Seoul 2022] POSTGRES 테스트코드로 기여하기 - 이동욱
[pgday.Seoul 2022] POSTGRES 테스트코드로 기여하기 - 이동욱
 
Top 10 Mistakes When Migrating From Oracle to PostgreSQL
Top 10 Mistakes When Migrating From Oracle to PostgreSQLTop 10 Mistakes When Migrating From Oracle to PostgreSQL
Top 10 Mistakes When Migrating From Oracle to PostgreSQL
 
ClickHouse Data Warehouse 101: The First Billion Rows, by Alexander Zaitsev a...
ClickHouse Data Warehouse 101: The First Billion Rows, by Alexander Zaitsev a...ClickHouse Data Warehouse 101: The First Billion Rows, by Alexander Zaitsev a...
ClickHouse Data Warehouse 101: The First Billion Rows, by Alexander Zaitsev a...
 
OpenGurukul : Database : PostgreSQL
OpenGurukul : Database : PostgreSQLOpenGurukul : Database : PostgreSQL
OpenGurukul : Database : PostgreSQL
 
Query logging with proxysql
Query logging with proxysqlQuery logging with proxysql
Query logging with proxysql
 
ClickHouse materialized views - a secret weapon for high performance analytic...
ClickHouse materialized views - a secret weapon for high performance analytic...ClickHouse materialized views - a secret weapon for high performance analytic...
ClickHouse materialized views - a secret weapon for high performance analytic...
 
Ceph: Open Source Storage Software Optimizations on Intel® Architecture for C...
Ceph: Open Source Storage Software Optimizations on Intel® Architecture for C...Ceph: Open Source Storage Software Optimizations on Intel® Architecture for C...
Ceph: Open Source Storage Software Optimizations on Intel® Architecture for C...
 
Patroni - HA PostgreSQL made easy
Patroni - HA PostgreSQL made easyPatroni - HA PostgreSQL made easy
Patroni - HA PostgreSQL made easy
 

Similar to Tips on how to improve the performance of your custom modules for high volumes deployment. Olivier Dony, OpenERP

Nginx Scripting - Extending Nginx Functionalities with Lua
Nginx Scripting - Extending Nginx Functionalities with LuaNginx Scripting - Extending Nginx Functionalities with Lua
Nginx Scripting - Extending Nginx Functionalities with LuaTony Fabeen
 
Devinsampa nginx-scripting
Devinsampa nginx-scriptingDevinsampa nginx-scripting
Devinsampa nginx-scriptingTony Fabeen
 
Application Logging in the 21st century - 2014.key
Application Logging in the 21st century - 2014.keyApplication Logging in the 21st century - 2014.key
Application Logging in the 21st century - 2014.keyTim Bunce
 
Node.js Event Loop & EventEmitter
Node.js Event Loop & EventEmitterNode.js Event Loop & EventEmitter
Node.js Event Loop & EventEmitterSimen Li
 
11 Things About 11gr2
11 Things About 11gr211 Things About 11gr2
11 Things About 11gr2afa reg
 
Speed up R with parallel programming in the Cloud
Speed up R with parallel programming in the CloudSpeed up R with parallel programming in the Cloud
Speed up R with parallel programming in the CloudRevolution Analytics
 
Introduction to Java Profiling
Introduction to Java ProfilingIntroduction to Java Profiling
Introduction to Java ProfilingJerry Yoakum
 
Splunk conf2014 - Lesser Known Commands in Splunk Search Processing Language ...
Splunk conf2014 - Lesser Known Commands in Splunk Search Processing Language ...Splunk conf2014 - Lesser Known Commands in Splunk Search Processing Language ...
Splunk conf2014 - Lesser Known Commands in Splunk Search Processing Language ...Splunk
 
Ceph Day Melbourne - Troubleshooting Ceph
Ceph Day Melbourne - Troubleshooting Ceph Ceph Day Melbourne - Troubleshooting Ceph
Ceph Day Melbourne - Troubleshooting Ceph Ceph Community
 
OSMC 2012 | Neues in Nagios 4.0 by Andreas Ericsson
OSMC 2012 | Neues in Nagios 4.0 by Andreas EricssonOSMC 2012 | Neues in Nagios 4.0 by Andreas Ericsson
OSMC 2012 | Neues in Nagios 4.0 by Andreas EricssonNETWAYS
 
Dynamic Tracing of your AMP web site
Dynamic Tracing of your AMP web siteDynamic Tracing of your AMP web site
Dynamic Tracing of your AMP web siteSriram Natarajan
 
HC-4021, Efficient scheduling of OpenMP and OpenCL™ workloads on Accelerated ...
HC-4021, Efficient scheduling of OpenMP and OpenCL™ workloads on Accelerated ...HC-4021, Efficient scheduling of OpenMP and OpenCL™ workloads on Accelerated ...
HC-4021, Efficient scheduling of OpenMP and OpenCL™ workloads on Accelerated ...AMD Developer Central
 
SplunkLive! Washington DC May 2013 - Splunk Security Workshop
SplunkLive! Washington DC May 2013 - Splunk Security WorkshopSplunkLive! Washington DC May 2013 - Splunk Security Workshop
SplunkLive! Washington DC May 2013 - Splunk Security WorkshopSplunk
 
Optimizing Performance - Clojure Remote - Nikola Peric
Optimizing Performance - Clojure Remote - Nikola PericOptimizing Performance - Clojure Remote - Nikola Peric
Optimizing Performance - Clojure Remote - Nikola PericNik Peric
 
Linux Systems Performance 2016
Linux Systems Performance 2016Linux Systems Performance 2016
Linux Systems Performance 2016Brendan Gregg
 
Docker Logging and analysing with Elastic Stack - Jakub Hajek
Docker Logging and analysing with Elastic Stack - Jakub Hajek Docker Logging and analysing with Elastic Stack - Jakub Hajek
Docker Logging and analysing with Elastic Stack - Jakub Hajek PROIDEA
 

Similar to Tips on how to improve the performance of your custom modules for high volumes deployment. Olivier Dony, OpenERP (20)

Nginx Scripting - Extending Nginx Functionalities with Lua
Nginx Scripting - Extending Nginx Functionalities with LuaNginx Scripting - Extending Nginx Functionalities with Lua
Nginx Scripting - Extending Nginx Functionalities with Lua
 
Devinsampa nginx-scripting
Devinsampa nginx-scriptingDevinsampa nginx-scripting
Devinsampa nginx-scripting
 
Osol Pgsql
Osol PgsqlOsol Pgsql
Osol Pgsql
 
Application Logging in the 21st century - 2014.key
Application Logging in the 21st century - 2014.keyApplication Logging in the 21st century - 2014.key
Application Logging in the 21st century - 2014.key
 
Node.js Event Loop & EventEmitter
Node.js Event Loop & EventEmitterNode.js Event Loop & EventEmitter
Node.js Event Loop & EventEmitter
 
11 Things About 11gr2
11 Things About 11gr211 Things About 11gr2
11 Things About 11gr2
 
Speed up R with parallel programming in the Cloud
Speed up R with parallel programming in the CloudSpeed up R with parallel programming in the Cloud
Speed up R with parallel programming in the Cloud
 
sun solaris
sun solarissun solaris
sun solaris
 
Introduction to Java Profiling
Introduction to Java ProfilingIntroduction to Java Profiling
Introduction to Java Profiling
 
Splunk conf2014 - Lesser Known Commands in Splunk Search Processing Language ...
Splunk conf2014 - Lesser Known Commands in Splunk Search Processing Language ...Splunk conf2014 - Lesser Known Commands in Splunk Search Processing Language ...
Splunk conf2014 - Lesser Known Commands in Splunk Search Processing Language ...
 
Ceph Day Melbourne - Troubleshooting Ceph
Ceph Day Melbourne - Troubleshooting Ceph Ceph Day Melbourne - Troubleshooting Ceph
Ceph Day Melbourne - Troubleshooting Ceph
 
OSMC 2012 | Neues in Nagios 4.0 by Andreas Ericsson
OSMC 2012 | Neues in Nagios 4.0 by Andreas EricssonOSMC 2012 | Neues in Nagios 4.0 by Andreas Ericsson
OSMC 2012 | Neues in Nagios 4.0 by Andreas Ericsson
 
Bioinformatica p4-io
Bioinformatica p4-ioBioinformatica p4-io
Bioinformatica p4-io
 
Dynamic Tracing of your AMP web site
Dynamic Tracing of your AMP web siteDynamic Tracing of your AMP web site
Dynamic Tracing of your AMP web site
 
HC-4021, Efficient scheduling of OpenMP and OpenCL™ workloads on Accelerated ...
HC-4021, Efficient scheduling of OpenMP and OpenCL™ workloads on Accelerated ...HC-4021, Efficient scheduling of OpenMP and OpenCL™ workloads on Accelerated ...
HC-4021, Efficient scheduling of OpenMP and OpenCL™ workloads on Accelerated ...
 
SplunkLive! Washington DC May 2013 - Splunk Security Workshop
SplunkLive! Washington DC May 2013 - Splunk Security WorkshopSplunkLive! Washington DC May 2013 - Splunk Security Workshop
SplunkLive! Washington DC May 2013 - Splunk Security Workshop
 
Optimizing Performance - Clojure Remote - Nikola Peric
Optimizing Performance - Clojure Remote - Nikola PericOptimizing Performance - Clojure Remote - Nikola Peric
Optimizing Performance - Clojure Remote - Nikola Peric
 
pm1
pm1pm1
pm1
 
Linux Systems Performance 2016
Linux Systems Performance 2016Linux Systems Performance 2016
Linux Systems Performance 2016
 
Docker Logging and analysing with Elastic Stack - Jakub Hajek
Docker Logging and analysing with Elastic Stack - Jakub Hajek Docker Logging and analysing with Elastic Stack - Jakub Hajek
Docker Logging and analysing with Elastic Stack - Jakub Hajek
 

More from Odoo

Timesheet Workshop: The Timesheet App People Love!
Timesheet Workshop: The Timesheet App People Love!Timesheet Workshop: The Timesheet App People Love!
Timesheet Workshop: The Timesheet App People Love!Odoo
 
Odoo 3D Product View with Google Model-Viewer
Odoo 3D Product View with Google Model-ViewerOdoo 3D Product View with Google Model-Viewer
Odoo 3D Product View with Google Model-ViewerOdoo
 
Keynote - Vision & Strategy
Keynote - Vision & StrategyKeynote - Vision & Strategy
Keynote - Vision & StrategyOdoo
 
Opening Keynote - Unveilling Odoo 14
Opening Keynote - Unveilling Odoo 14Opening Keynote - Unveilling Odoo 14
Opening Keynote - Unveilling Odoo 14Odoo
 
Extending Odoo with a Comprehensive Budgeting and Forecasting Capability
Extending Odoo with a Comprehensive Budgeting and Forecasting CapabilityExtending Odoo with a Comprehensive Budgeting and Forecasting Capability
Extending Odoo with a Comprehensive Budgeting and Forecasting CapabilityOdoo
 
Managing Multi-channel Selling with Odoo
Managing Multi-channel Selling with OdooManaging Multi-channel Selling with Odoo
Managing Multi-channel Selling with OdooOdoo
 
Product Configurator: Advanced Use Case
Product Configurator: Advanced Use CaseProduct Configurator: Advanced Use Case
Product Configurator: Advanced Use CaseOdoo
 
Accounting Automation: How Much Money We Saved and How?
Accounting Automation: How Much Money We Saved and How?Accounting Automation: How Much Money We Saved and How?
Accounting Automation: How Much Money We Saved and How?Odoo
 
Rock Your Logistics with Advanced Operations
Rock Your Logistics with Advanced OperationsRock Your Logistics with Advanced Operations
Rock Your Logistics with Advanced OperationsOdoo
 
Transition from a cost to a flow-centric organization
Transition from a cost to a flow-centric organizationTransition from a cost to a flow-centric organization
Transition from a cost to a flow-centric organizationOdoo
 
Synchronization: The Supply Chain Response to Overcome the Crisis
Synchronization: The Supply Chain Response to Overcome the CrisisSynchronization: The Supply Chain Response to Overcome the Crisis
Synchronization: The Supply Chain Response to Overcome the CrisisOdoo
 
Running a University with Odoo
Running a University with OdooRunning a University with Odoo
Running a University with OdooOdoo
 
Down Payments on Purchase Orders in Odoo
Down Payments on Purchase Orders in OdooDown Payments on Purchase Orders in Odoo
Down Payments on Purchase Orders in OdooOdoo
 
Odoo Implementation in Phases - Success Story of a Retail Chain 3Sach food
Odoo Implementation in Phases - Success Story of a Retail Chain 3Sach foodOdoo Implementation in Phases - Success Story of a Retail Chain 3Sach food
Odoo Implementation in Phases - Success Story of a Retail Chain 3Sach foodOdoo
 
Migration from Salesforce to Odoo
Migration from Salesforce to OdooMigration from Salesforce to Odoo
Migration from Salesforce to OdooOdoo
 
Preventing User Mistakes by Using Machine Learning
Preventing User Mistakes by Using Machine LearningPreventing User Mistakes by Using Machine Learning
Preventing User Mistakes by Using Machine LearningOdoo
 
Becoming an Odoo Expert: How to Prepare for the Certification
Becoming an Odoo Expert: How to Prepare for the Certification Becoming an Odoo Expert: How to Prepare for the Certification
Becoming an Odoo Expert: How to Prepare for the Certification Odoo
 
Instant Printing of any Odoo Report or Shipping Label
Instant Printing of any Odoo Report or Shipping LabelInstant Printing of any Odoo Report or Shipping Label
Instant Printing of any Odoo Report or Shipping LabelOdoo
 
How Odoo helped an Organization Grow 3 Fold
How Odoo helped an Organization Grow 3 FoldHow Odoo helped an Organization Grow 3 Fold
How Odoo helped an Organization Grow 3 FoldOdoo
 
From Shopify to Odoo
From Shopify to OdooFrom Shopify to Odoo
From Shopify to OdooOdoo
 

More from Odoo (20)

Timesheet Workshop: The Timesheet App People Love!
Timesheet Workshop: The Timesheet App People Love!Timesheet Workshop: The Timesheet App People Love!
Timesheet Workshop: The Timesheet App People Love!
 
Odoo 3D Product View with Google Model-Viewer
Odoo 3D Product View with Google Model-ViewerOdoo 3D Product View with Google Model-Viewer
Odoo 3D Product View with Google Model-Viewer
 
Keynote - Vision & Strategy
Keynote - Vision & StrategyKeynote - Vision & Strategy
Keynote - Vision & Strategy
 
Opening Keynote - Unveilling Odoo 14
Opening Keynote - Unveilling Odoo 14Opening Keynote - Unveilling Odoo 14
Opening Keynote - Unveilling Odoo 14
 
Extending Odoo with a Comprehensive Budgeting and Forecasting Capability
Extending Odoo with a Comprehensive Budgeting and Forecasting CapabilityExtending Odoo with a Comprehensive Budgeting and Forecasting Capability
Extending Odoo with a Comprehensive Budgeting and Forecasting Capability
 
Managing Multi-channel Selling with Odoo
Managing Multi-channel Selling with OdooManaging Multi-channel Selling with Odoo
Managing Multi-channel Selling with Odoo
 
Product Configurator: Advanced Use Case
Product Configurator: Advanced Use CaseProduct Configurator: Advanced Use Case
Product Configurator: Advanced Use Case
 
Accounting Automation: How Much Money We Saved and How?
Accounting Automation: How Much Money We Saved and How?Accounting Automation: How Much Money We Saved and How?
Accounting Automation: How Much Money We Saved and How?
 
Rock Your Logistics with Advanced Operations
Rock Your Logistics with Advanced OperationsRock Your Logistics with Advanced Operations
Rock Your Logistics with Advanced Operations
 
Transition from a cost to a flow-centric organization
Transition from a cost to a flow-centric organizationTransition from a cost to a flow-centric organization
Transition from a cost to a flow-centric organization
 
Synchronization: The Supply Chain Response to Overcome the Crisis
Synchronization: The Supply Chain Response to Overcome the CrisisSynchronization: The Supply Chain Response to Overcome the Crisis
Synchronization: The Supply Chain Response to Overcome the Crisis
 
Running a University with Odoo
Running a University with OdooRunning a University with Odoo
Running a University with Odoo
 
Down Payments on Purchase Orders in Odoo
Down Payments on Purchase Orders in OdooDown Payments on Purchase Orders in Odoo
Down Payments on Purchase Orders in Odoo
 
Odoo Implementation in Phases - Success Story of a Retail Chain 3Sach food
Odoo Implementation in Phases - Success Story of a Retail Chain 3Sach foodOdoo Implementation in Phases - Success Story of a Retail Chain 3Sach food
Odoo Implementation in Phases - Success Story of a Retail Chain 3Sach food
 
Migration from Salesforce to Odoo
Migration from Salesforce to OdooMigration from Salesforce to Odoo
Migration from Salesforce to Odoo
 
Preventing User Mistakes by Using Machine Learning
Preventing User Mistakes by Using Machine LearningPreventing User Mistakes by Using Machine Learning
Preventing User Mistakes by Using Machine Learning
 
Becoming an Odoo Expert: How to Prepare for the Certification
Becoming an Odoo Expert: How to Prepare for the Certification Becoming an Odoo Expert: How to Prepare for the Certification
Becoming an Odoo Expert: How to Prepare for the Certification
 
Instant Printing of any Odoo Report or Shipping Label
Instant Printing of any Odoo Report or Shipping LabelInstant Printing of any Odoo Report or Shipping Label
Instant Printing of any Odoo Report or Shipping Label
 
How Odoo helped an Organization Grow 3 Fold
How Odoo helped an Organization Grow 3 FoldHow Odoo helped an Organization Grow 3 Fold
How Odoo helped an Organization Grow 3 Fold
 
From Shopify to Odoo
From Shopify to OdooFrom Shopify to Odoo
From Shopify to Odoo
 

Recently uploaded

Mysore Call Girls 8617370543 WhatsApp Number 24x7 Best Services
Mysore Call Girls 8617370543 WhatsApp Number 24x7 Best ServicesMysore Call Girls 8617370543 WhatsApp Number 24x7 Best Services
Mysore Call Girls 8617370543 WhatsApp Number 24x7 Best ServicesDipal Arora
 
Value Proposition canvas- Customer needs and pains
Value Proposition canvas- Customer needs and painsValue Proposition canvas- Customer needs and pains
Value Proposition canvas- Customer needs and painsP&CO
 
Pharma Works Profile of Karan Communications
Pharma Works Profile of Karan CommunicationsPharma Works Profile of Karan Communications
Pharma Works Profile of Karan Communicationskarancommunications
 
M.C Lodges -- Guest House in Jhang.
M.C Lodges --  Guest House in Jhang.M.C Lodges --  Guest House in Jhang.
M.C Lodges -- Guest House in Jhang.Aaiza Hassan
 
RSA Conference Exhibitor List 2024 - Exhibitors Data
RSA Conference Exhibitor List 2024 - Exhibitors DataRSA Conference Exhibitor List 2024 - Exhibitors Data
RSA Conference Exhibitor List 2024 - Exhibitors DataExhibitors Data
 
Best VIP Call Girls Noida Sector 40 Call Me: 8448380779
Best VIP Call Girls Noida Sector 40 Call Me: 8448380779Best VIP Call Girls Noida Sector 40 Call Me: 8448380779
Best VIP Call Girls Noida Sector 40 Call Me: 8448380779Delhi Call girls
 
A DAY IN THE LIFE OF A SALESMAN / WOMAN
A DAY IN THE LIFE OF A  SALESMAN / WOMANA DAY IN THE LIFE OF A  SALESMAN / WOMAN
A DAY IN THE LIFE OF A SALESMAN / WOMANIlamathiKannappan
 
Call Girls In DLf Gurgaon ➥99902@11544 ( Best price)100% Genuine Escort In 24...
Call Girls In DLf Gurgaon ➥99902@11544 ( Best price)100% Genuine Escort In 24...Call Girls In DLf Gurgaon ➥99902@11544 ( Best price)100% Genuine Escort In 24...
Call Girls In DLf Gurgaon ➥99902@11544 ( Best price)100% Genuine Escort In 24...lizamodels9
 
How to Get Started in Social Media for Art League City
How to Get Started in Social Media for Art League CityHow to Get Started in Social Media for Art League City
How to Get Started in Social Media for Art League CityEric T. Tung
 
It will be International Nurses' Day on 12 May
It will be International Nurses' Day on 12 MayIt will be International Nurses' Day on 12 May
It will be International Nurses' Day on 12 MayNZSG
 
Enhancing and Restoring Safety & Quality Cultures - Dave Litwiller - May 2024...
Enhancing and Restoring Safety & Quality Cultures - Dave Litwiller - May 2024...Enhancing and Restoring Safety & Quality Cultures - Dave Litwiller - May 2024...
Enhancing and Restoring Safety & Quality Cultures - Dave Litwiller - May 2024...Dave Litwiller
 
VIP Call Girls In Saharaganj ( Lucknow ) 🔝 8923113531 🔝 Cash Payment (COD) 👒
VIP Call Girls In Saharaganj ( Lucknow  ) 🔝 8923113531 🔝  Cash Payment (COD) 👒VIP Call Girls In Saharaganj ( Lucknow  ) 🔝 8923113531 🔝  Cash Payment (COD) 👒
VIP Call Girls In Saharaganj ( Lucknow ) 🔝 8923113531 🔝 Cash Payment (COD) 👒anilsa9823
 
B.COM Unit – 4 ( CORPORATE SOCIAL RESPONSIBILITY ( CSR ).pptx
B.COM Unit – 4 ( CORPORATE SOCIAL RESPONSIBILITY ( CSR ).pptxB.COM Unit – 4 ( CORPORATE SOCIAL RESPONSIBILITY ( CSR ).pptx
B.COM Unit – 4 ( CORPORATE SOCIAL RESPONSIBILITY ( CSR ).pptxpriyanshujha201
 
Russian Call Girls In Gurgaon ❤️8448577510 ⊹Best Escorts Service In 24/7 Delh...
Russian Call Girls In Gurgaon ❤️8448577510 ⊹Best Escorts Service In 24/7 Delh...Russian Call Girls In Gurgaon ❤️8448577510 ⊹Best Escorts Service In 24/7 Delh...
Russian Call Girls In Gurgaon ❤️8448577510 ⊹Best Escorts Service In 24/7 Delh...lizamodels9
 
John Halpern sued for sexual assault.pdf
John Halpern sued for sexual assault.pdfJohn Halpern sued for sexual assault.pdf
John Halpern sued for sexual assault.pdfAmzadHosen3
 
Insurers' journeys to build a mastery in the IoT usage
Insurers' journeys to build a mastery in the IoT usageInsurers' journeys to build a mastery in the IoT usage
Insurers' journeys to build a mastery in the IoT usageMatteo Carbone
 
FULL ENJOY Call Girls In Majnu Ka Tilla, Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Majnu Ka Tilla, Delhi Contact Us 8377877756FULL ENJOY Call Girls In Majnu Ka Tilla, Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Majnu Ka Tilla, Delhi Contact Us 8377877756dollysharma2066
 

Recently uploaded (20)

Mysore Call Girls 8617370543 WhatsApp Number 24x7 Best Services
Mysore Call Girls 8617370543 WhatsApp Number 24x7 Best ServicesMysore Call Girls 8617370543 WhatsApp Number 24x7 Best Services
Mysore Call Girls 8617370543 WhatsApp Number 24x7 Best Services
 
VVVIP Call Girls In Greater Kailash ➡️ Delhi ➡️ 9999965857 🚀 No Advance 24HRS...
VVVIP Call Girls In Greater Kailash ➡️ Delhi ➡️ 9999965857 🚀 No Advance 24HRS...VVVIP Call Girls In Greater Kailash ➡️ Delhi ➡️ 9999965857 🚀 No Advance 24HRS...
VVVIP Call Girls In Greater Kailash ➡️ Delhi ➡️ 9999965857 🚀 No Advance 24HRS...
 
Value Proposition canvas- Customer needs and pains
Value Proposition canvas- Customer needs and painsValue Proposition canvas- Customer needs and pains
Value Proposition canvas- Customer needs and pains
 
Pharma Works Profile of Karan Communications
Pharma Works Profile of Karan CommunicationsPharma Works Profile of Karan Communications
Pharma Works Profile of Karan Communications
 
M.C Lodges -- Guest House in Jhang.
M.C Lodges --  Guest House in Jhang.M.C Lodges --  Guest House in Jhang.
M.C Lodges -- Guest House in Jhang.
 
RSA Conference Exhibitor List 2024 - Exhibitors Data
RSA Conference Exhibitor List 2024 - Exhibitors DataRSA Conference Exhibitor List 2024 - Exhibitors Data
RSA Conference Exhibitor List 2024 - Exhibitors Data
 
Best VIP Call Girls Noida Sector 40 Call Me: 8448380779
Best VIP Call Girls Noida Sector 40 Call Me: 8448380779Best VIP Call Girls Noida Sector 40 Call Me: 8448380779
Best VIP Call Girls Noida Sector 40 Call Me: 8448380779
 
A DAY IN THE LIFE OF A SALESMAN / WOMAN
A DAY IN THE LIFE OF A  SALESMAN / WOMANA DAY IN THE LIFE OF A  SALESMAN / WOMAN
A DAY IN THE LIFE OF A SALESMAN / WOMAN
 
Call Girls In DLf Gurgaon ➥99902@11544 ( Best price)100% Genuine Escort In 24...
Call Girls In DLf Gurgaon ➥99902@11544 ( Best price)100% Genuine Escort In 24...Call Girls In DLf Gurgaon ➥99902@11544 ( Best price)100% Genuine Escort In 24...
Call Girls In DLf Gurgaon ➥99902@11544 ( Best price)100% Genuine Escort In 24...
 
How to Get Started in Social Media for Art League City
How to Get Started in Social Media for Art League CityHow to Get Started in Social Media for Art League City
How to Get Started in Social Media for Art League City
 
Mifty kit IN Salmiya (+918133066128) Abortion pills IN Salmiyah Cytotec pills
Mifty kit IN Salmiya (+918133066128) Abortion pills IN Salmiyah Cytotec pillsMifty kit IN Salmiya (+918133066128) Abortion pills IN Salmiyah Cytotec pills
Mifty kit IN Salmiya (+918133066128) Abortion pills IN Salmiyah Cytotec pills
 
It will be International Nurses' Day on 12 May
It will be International Nurses' Day on 12 MayIt will be International Nurses' Day on 12 May
It will be International Nurses' Day on 12 May
 
Enhancing and Restoring Safety & Quality Cultures - Dave Litwiller - May 2024...
Enhancing and Restoring Safety & Quality Cultures - Dave Litwiller - May 2024...Enhancing and Restoring Safety & Quality Cultures - Dave Litwiller - May 2024...
Enhancing and Restoring Safety & Quality Cultures - Dave Litwiller - May 2024...
 
VIP Call Girls In Saharaganj ( Lucknow ) 🔝 8923113531 🔝 Cash Payment (COD) 👒
VIP Call Girls In Saharaganj ( Lucknow  ) 🔝 8923113531 🔝  Cash Payment (COD) 👒VIP Call Girls In Saharaganj ( Lucknow  ) 🔝 8923113531 🔝  Cash Payment (COD) 👒
VIP Call Girls In Saharaganj ( Lucknow ) 🔝 8923113531 🔝 Cash Payment (COD) 👒
 
unwanted pregnancy Kit [+918133066128] Abortion Pills IN Dubai UAE Abudhabi
unwanted pregnancy Kit [+918133066128] Abortion Pills IN Dubai UAE Abudhabiunwanted pregnancy Kit [+918133066128] Abortion Pills IN Dubai UAE Abudhabi
unwanted pregnancy Kit [+918133066128] Abortion Pills IN Dubai UAE Abudhabi
 
B.COM Unit – 4 ( CORPORATE SOCIAL RESPONSIBILITY ( CSR ).pptx
B.COM Unit – 4 ( CORPORATE SOCIAL RESPONSIBILITY ( CSR ).pptxB.COM Unit – 4 ( CORPORATE SOCIAL RESPONSIBILITY ( CSR ).pptx
B.COM Unit – 4 ( CORPORATE SOCIAL RESPONSIBILITY ( CSR ).pptx
 
Russian Call Girls In Gurgaon ❤️8448577510 ⊹Best Escorts Service In 24/7 Delh...
Russian Call Girls In Gurgaon ❤️8448577510 ⊹Best Escorts Service In 24/7 Delh...Russian Call Girls In Gurgaon ❤️8448577510 ⊹Best Escorts Service In 24/7 Delh...
Russian Call Girls In Gurgaon ❤️8448577510 ⊹Best Escorts Service In 24/7 Delh...
 
John Halpern sued for sexual assault.pdf
John Halpern sued for sexual assault.pdfJohn Halpern sued for sexual assault.pdf
John Halpern sued for sexual assault.pdf
 
Insurers' journeys to build a mastery in the IoT usage
Insurers' journeys to build a mastery in the IoT usageInsurers' journeys to build a mastery in the IoT usage
Insurers' journeys to build a mastery in the IoT usage
 
FULL ENJOY Call Girls In Majnu Ka Tilla, Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Majnu Ka Tilla, Delhi Contact Us 8377877756FULL ENJOY Call Girls In Majnu Ka Tilla, Delhi Contact Us 8377877756
FULL ENJOY Call Girls In Majnu Ka Tilla, Delhi Contact Us 8377877756
 

Tips on how to improve the performance of your custom modules for high volumes deployment. Olivier Dony, OpenERP

  • 2. OpenERP can handle large volumes of transactions and large volumes of data out of the box!
  • 3. For example, each OpenERP Online Server hosts 1000+ databases without breaking a sweat!
  • 4. Many on-site customers have single server deployments with millions of rows: partners, emails, attachments, journal items, stock moves, workflow items, …
  • 5. What if performance is an issue? Get the right facts. Use the right tools.
  • 6. t @odony Agenda ● Architecture / Deployment / Sizing ● Measuring & Analyzing ● Common Problems ● Anti-patterns
  • 8. PostgreSQL is the real workhorse behind OpenERP, and it scales very well!
  • 9. t @odony OpenERP Cron Worker Deployment Architecture: single server, multi-process Rule of thumb: --workers=$((1+${CORES}*2)) OpenERP HTTP Worker OpenERP HTTP Worker OpenERP HTTP Worker OpenERP HTTP Worker PostgreSQL Requests
  • 10. t @odony OpenERP Cron Worker Deployment Architecture: multi-server, multi-process OpenERP HTTP Worker OpenERP HTTP Worker OpenERP HTTP Worker OpenERP HTTP Worker PostgreSQL Requests Server 3 Load Balancer OpenERP Cron Worker OpenERP HTTP Worker OpenERP HTTP Worker OpenERP HTTP Worker OpenERP HTTP Worker Server 2 Server 1
  • 11. t @odony Hardware Sizing ● Typical modern server machine ● 4/8/12 2+GHz cores ● 8-64 GB RAM ● Fast SATA/SAS/SSD disks ● Up to 100-200 active users (multi-process) ● Up to dozens of HTTP requests per second ● Up to 1000 “light” users (average SaaS user) ● For official OpenERP 7.0 deployments with no customizations, and typical usage!
  • 12. For anything else, always perform proper load testing before going live in production! Then size accordingly...
  • 13. t @odony PostgreSQL Deployment tips ● Avoid deploying PostgreSQL on a VM ● If you must do it, fine-tune the VM for I/O! ● And always check out the basic PostgreSQL performance tuning, it's conservative by default http://wiki.postgresql.org/wiki/Tuning_Your_PostgreSQL_Server
  • 14. t @odony Agenda ● Architecture / Deployment / Sizing ● Measuring & Analyzing ● Common Problems ● Anti-patterns
  • 15. t @odony Monitor application response times ● You can't manage/improve what you can't measure ● Setup an automated monitoring of performance and response time... even if you have no performance problem! ● Suggested tool: munin ● Run OpenERP with –log-level=debug_rpc in prod! 2013-07-03 00:12:29,846 9663 DEBUG test openerp.netsvc.rpc.request: object.execute_kw time:0.031s mem: 763716k -> 763716k (diff: 0k)('test', 1, '*', 'sale.order', 'read', (...), {...})
  • 16. t @odony #!/bin/sh #%# family=manual #%# capabilities=autoconf suggest case $1 in autoconf) exit 0 ;; suggest) exit 0 ;; config) echo graph_category openerp echo graph_title openerp rpc request count echo graph_vlabel num requests/minute in last 5 minutes echo requests.label num requests exit 0 ;; esac # watch out for the time zone of the logs => using date -u for UTC timestamps result=$(tail -60000 /var/log/openerp.log | grep "object.execute_kw time" | awk "BEGIN{count=0} ($1 " " $2) >= "`date +'%F %H:%M:%S' -ud '5 min ago'`" { count+=1; } END{print count/5}") echo "requests.value ${result}" exit 0 Munin plugin: OpenERP requests/minute
  • 17. t @odony #!/bin/sh #%# family=manual #%# capabilities=autoconf suggest case $1 in config) echo graph_category openerp echo graph_title openerp rpc requests min/average response time echo graph_vlabel seconds echo graph_args --units-exponent -3 echo min.label min echo min.warning 1 echo min.critical 5 echo avg.label average echo avg.warning 1 echo avg.critical 5 exit 0 ;; esac # watch out for the time zone of the logs => using date -u for UTC timestamps result=$(tail -60000 /var/log/openerp.log | grep "object.execute_kw time" | awk "BEGIN{sum=0;count=0} ( $1 " " $2) >= "`date +'%F %H:%M:%S' -ud '5 min ago'`" {split($8,t,":");time=0+t[2];if (min=="") { min=time}; sum += time; count+=1; min=(time>min)?min:time } END{print min, sum/count}") echo -n "min.value " echo ${result} | cut -d" " -f1 echo -n "avg.value " echo ${result} | cut -d" " -f2 exit 0 Munin plugin: OpenERP min/avg response time
  • 18. t @odony #!/bin/sh #%# family=manual #%# capabilities=autoconf suggest case $1 in config) echo graph_category openerp echo graph_title openerp rpc requests max response time echo graph_vlabel seconds echo graph_args --units-exponent -3 echo max.label max echo max.warning 1 echo max.critical 5 exit 0 ;;.. esac # watch out for the time zone of the logs => using date -u for UTC timestamps.... result=$(tail -60000 /var/log/openerp.log | grep "object.execute_kw time" | awk "BEGIN{sum=0;count=0} ( $1 " " $2) >= "`date +'%F %H:%M:%S' -ud '85 min ago'`" {split($8,t,":");time=0+t[2]; sum += time; count+=1; max=(time<max)?max:time } END{print max}") echo "max.value ${result}" exit 0 Munin plugin: OpenERP max response time
  • 19. t @odony Monitor PostgreSQL ● postgresql.conf ● log_min_duration_statement = 50 ● Set to 50 or 100 in production ● Set to 0 to log all queries and execution times for a while ● Instagram gist to capture sample + analyze ● Analyze with pgBadger or pgFouine ● lc_messages = 'C'
  • 20. t @odony PostgreSQL Analysis ● Important PG statistic tables ● pg_stat_activity: near real-time view of transactions ● pg_locks: real-time view of existing locks ● pg_stat_user_tables: generic usage stats for all tables ● pg_statio_user_tables: generic I/O stats for all tables
  • 21. t @odony PostgreSQL Analysis: longest tables # SELECT schemaname || '.' || relname as table,n_live_tup as num_rows FROM pg_stat_user_tables ORDER BY n_live_tup DESC limit 10; ┌──────────────────────────────────────────┬──────────┐ │ table │ num_rows │ ├──────────────────────────────────────────┼──────────┤ │ public.stock_move │ 179544 │ │ public.ir_translation │ 134039 │ │ public.wkf_workitem │ 97195 │ │ public.wkf_instance │ 96973 │ │ public.procurement_order │ 83077 │ │ public.ir_property │ 69011 │ │ public.ir_model_data │ 59532 │ │ public.stock_move_history_ids │ 58942 │ │ public.mrp_production_move_ids │ 49714 │ │ public.mrp_bom │ 46258 │ └──────────────────────────────────────────┴──────────┘
  • 22. t @odony PostgreSQL Analysis: biggest tables # SELECT nspname || '.' || relname AS "table", pg_size_pretty(pg_total_relation_size(C.oid)) AS "total_size" FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace) WHERE nspname NOT IN ('pg_catalog', 'information_schema') AND C.relkind <> 'i' AND nspname !~ '^pg_toast' ORDER BY pg_total_relation_size(C.oid) DESC LIMIT 10; ┌──────────────────────────────────────────┬────────────┐ │ table │ total_size │ ├──────────────────────────────────────────┼────────────┤ │ public.stock_move │ 525 MB │ │ public.wkf_workitem │ 111 MB │ │ public.procurement_order │ 80 MB │ │ public.stock_location │ 63 MB │ │ public.ir_translation │ 42 MB │ │ public.wkf_instance │ 37 MB │ │ public.ir_model_data │ 36 MB │ │ public.ir_property │ 26 MB │ │ public.ir_attachment │ 14 MB │ │ public.mrp_bom │ 13 MB │ └──────────────────────────────────────────┴────────────┘
  • 23. t @odony PostgreSQL Analysis: biggest tables ● Consider using the file storage for the ir.attachment table ● Avoid storing files in the database ● Greatly reduces the time needed for DB backups and backup ● Very easy to rsync backups of DB dumps + filestore ● For 7.0 this setting is explained in this FAQ
  • 24. t @odony PostgreSQL Analysis: most read tables # SELECT schemaname || '.' || relname as table, heap_blks_read as disk_reads, heap_blks_hit as cache_reads, heap_blks_read + heap_blks_hit as total_reads from pg_statio_user_tables order by heap_blks_read + heap_blks_hit desc limit 15; ┌───────────────────────────────┬────────────┬─────────────┬─────────────┐ │ table │ disk_reads │ cache_reads │ total_reads │ ├───────────────────────────────┼────────────┼─────────────┼─────────────┤ │ public.stock_location │ 53796 │ 60926676388 │ 60926730184 │ │ public.stock_move │ 208763 │ 9880525282 │ 9880734045 │ │ public.stock_picking │ 15772 │ 4659569791 │ 4659585563 │ │ public.procurement_order │ 156139 │ 1430660775 │ 1430816914 │ │ public.stock_tracking │ 2621 │ 525023173 │ 525025794 │ │ public.product_product │ 11178 │ 225774346 │ 225785524 │ │ public.mrp_bom │ 27198 │ 225329643 │ 225356841 │ │ public.ir_model_fields │ 1632 │ 203361139 │ 203362771 │ │ public.stock_production_lot │ 5918 │ 127915614 │ 127921532 │ │ public.res_users │ 416 │ 115506586 │ 115507002 │ │ public.ir_model_access │ 6382 │ 104686364 │ 104692746 │ │ public.mrp_production │ 20829 │ 101523983 │ 101544812 │ │ public.product_template │ 4566 │ 76074699 │ 76079265 │ │ public.product_uom │ 18 │ 70521126 │ 70521144 │ │ public.wkf_workitem │ 129166 │ 67782919 │ 67912085 │ └───────────────────────────────┴────────────┴─────────────┴─────────────┘
  • 25. t @odony PostgreSQL Analysis: most updated/inserted/... # SELECT schemaname || '.' || relname as table, seq_scan,idx_scan,idx_tup_fetch+seq_tup_read lines_read_total, n_tup_ins as num_insert,n_tup_upd as num_update,n_tup_del as num_delete from pg_stat_user_tables order by n_tup_upd desc limit 10; ┌────────────────────────────────────┬──────────┬────────────┬──────────────────┬────────────┬────────────┬────────────┐ │ table │ seq_scan │ idx_scan │ lines_read_total │ num_insert │ num_update │ num_delete │ ├────────────────────────────────────┼──────────┼────────────┼──────────────────┼────────────┼────────────┼────────────┤ │ public.stock_move │ 1188095 │ 1104711719 │ 132030135782 │ 208507 │ 9556574 │ 67298 │ │ public.procurement_order │ 226774 │ 22134417 │ 11794090805 │ 92064 │ 6882666 │ 27543 │ │ public.wkf_workitem │ 373 │ 17340039 │ 29910699 │ 1958392 │ 3280141 │ 1883794 │ │ public.stock_location │ 41402098 │ 166316501 │ 516216409246 │ 97 │ 2215107 │ 205 │ │ public.stock_picking │ 297984 │ 71732467 │ 5671488265 │ 9008 │ 1000966 │ 1954 │ │ public.stock_production_lot │ 190934 │ 28038527 │ 1124560295 │ 4318 │ 722053 │ 0 │ │ public.mrp_production │ 270568 │ 13550371 │ 476534514 │ 3816 │ 495776 │ 1883 │ │ public.sale_order_line │ 30161 │ 4757426 │ 60019207 │ 2077 │ 479752 │ 320 │ │ public.stock_tracking │ 656404 │ 97874788 │ 5054452666 │ 5914 │ 404469 │ 0 │ │ public.ir_cron │ 246636 │ 818 │ 2467441 │ 0 │ 169904 │ 0 │ └────────────────────────────────────┴──────────┴────────────┴──────────────────┴────────────┴────────────┴────────────┘
  • 26. t @odony Useful VIEW to watch locked queries -- For PostgreSQL 9.1 CREATE VIEW monitor_blocked_queries AS SELECT pg_class.relname, waiter.pid as blocked_pid, substr(wait_act.current_query,1,30) as blocked_statement, age(now(),wait_act.query_start) as blocked_duration, holder.pid as blocking_pid, substr(hold_act.current_query,1,30) as blocking_statement, age(now(),hold_act.query_start) as blocking_duration, waiter.transactionid as xid, waiter.mode as wmode, waiter.virtualtransaction as wvxid, holder.mode as hmode, holder.virtualtransaction as hvxid FROM pg_locks holder join pg_locks waiter on ( holder.locktype = waiter.locktype and ( holder.database, holder.relation, holder.page, holder.tuple, holder.virtualxid, holder.transactionid, holder.classid, holder.objid, holder.objsubid ) IS NOT DISTINCT from ( waiter.database, waiter.relation, waiter.page, waiter.tuple, waiter.virtualxid, waiter.transactionid, waiter.classid, waiter.objid, waiter.objsubid )) JOIN pg_stat_activity hold_act ON (holder.pid=hold_act.procpid) JOIN pg_stat_activity wait_act ON (waiter.pid=wait_act.procpid) LEFT JOIN pg_class ON (holder.relation = pg_class.oid) WHERE wait_act.datname = 'eurogerm' AND holder.granted AND NOT waiter.granted ORDER BY blocked_duration DESC;
  • 27. t @odony Useful VIEW to watch locked queries # SELECT * FROM blocked_queries; relname | blocked_pid | blocked_statement | blocked_duration | blocking_pid | blocking_statement ---------+-------------+--------------------------------+------------------+--------------+------------------------- | 16504 | update "stock_tracking" set "s | 00:00:57.588357 | 16338 | <IDLE> in transaction | 16501 | update "stock_tracking" set "f | 00:00:55.144373 | 16504 | update "stock_tracking" (2 lignes) ... | blocking_statement | blocking_duration | xid | wmode | hmode | ... +--------------------------------+-------------------+----------+-----------+---------------| ... | <IDLE> in transaction | -00:00:00.004754 | 12630740 | ShareLock | ExclusiveLock | ... | update "stock_tracking" set "s | 00:00:57.588357 | 12630722 | ShareLock | ExclusiveLock |
  • 28. t @odony Useful tool for watching activity: pg_activity top-like command-line utility to watch queries: running, blocking, waiting → pip install pg_activity Thanks to @cmorisse for this pointer! :-)
  • 29. t @odony Useful VIEW to watch Locks per transaction # – For PostgreSQL 9.1 # CREATE VIEW monitor_locks AS SELECT pg_stat_activity.procpid, pg_class.relname, pg_locks.locktype, pg_locks.transactionid, pg_locks.virtualxid, pg_locks.virtualtransaction, pg_locks.mode, pg_locks.granted, pg_stat_activity.usename, substr(pg_stat_activity.current_query,1,30) AS query, pg_stat_activity.query_start, age(now(),pg_stat_activity.query_start) AS duration FROM pg_stat_activity, pg_locks LEFT JOIN pg_class ON pg_locks.relation = pg_class.oid WHERE pg_locks.pid = pg_stat_activity.procpid AND pg_stat_activity.procpid != pg_backend_pid() ORDER BY pg_stat_activity.procpid, pg_locks.granted, pg_class.relname;
  • 30. t @odony Useful VIEW to watch Locks per transaction pid | relname | locktype | xid | virtualxid ------+-----------------------------------------------------------+------------------+----------+----------- 8597 | | transactionid | 12171567 | 11/164037 8597 | purchase_order_line_pkey | relation | | 11/164037 8597 | stock_location_location_id_index | relation | | 11/164037 8597 | stock_move_production_id_index | relation | | 11/164037 8597 | stock_move_production_id_index | relation | | 11/164037 8597 | stock_move_location_id_location_dest_id_product_id_state | relation | | 11/164037 8597 | multi_company_default | relation | | 11/164037 8597 | stock_picking_invoice_state_index | relation | | 11/164037 8597 | ir_model_access_group_id_index | relation | | 11/164037 8597 | purchase_order_line_date_planned_index | relation | | 11/164037 8597 | purchase_order_pkey | relation | | 11/164037 8597 | res_company | relation | | 11/164037 8597 | purchase_order_name_index | relation | | 11/164037 8597 | res_company | relation | | 11/164037 8597 | ir_sequence_pkey | relation | | 11/164037 8597 | ir_sequence_pkey | relation | | 11/164037 8597 | res_partner_company_id_index | relation | | 11/164037 8597 | product_product_have_pqcd_cde_index | relation | | 11/164037 8597 | stock_tracking | relation | | 11/164037 8597 | ir_translation_src_hash_idx | relation | | 11/164037 8597 | res_users | relation | | 11/164037 8597 | product_template_name_index | relation | | 11/164037 8597 | res_users | relation | | 11/164037 8597 | stock_move_tracking
  • 31. t @odony Useful VIEW to watch Locks per transaction | mode | granted | query | query_start | duration | +------------------+---------+--------------------------------+-------------------------------+------------------+ | AccessShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 | | AccessShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 | | AccessShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 | | AccessShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 | | RowExclusiveLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 | | AccessShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 | | AccessShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 | | AccessShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 | | AccessShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 | | AccessShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 | | AccessShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 | | AccessShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 | | AccessShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 | | RowShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 | | AccessShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 | | RowExclusiveLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 | | AccessShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 | | AccessShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 | | AccessShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 | | AccessShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 | | RowShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 | | AccessShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 | | AccessShareLock | t | <IDLE> in transaction | 2013-06-18 12:53:01.601039+02 | 00:00:00.278826 |
  • 32. t @odony Normal Values? ● Most RPC requests should be under 200ms ● Most SQL queries should be under 100ms ● One transaction = 100-300 heavyweight locks Find your own normal values via monitoring!
  • 33. t @odony Agenda ● Architecture / Deployment / Sizing ● Measuring & Analyzing ● Common Problems ● Anti-patterns
  • 34. t @odony Common Problems ● Stored functions ● Slow Queries/Views, Suboptimal domains ● Lock contention ● Custom locking mechanisms (queues, locks,...)
  • 35. t @odony Common Problems: Stored Functions ● Stored functional fields are triggers ● Store triggers can be: ● store = { 'trigger_model': (mapping_function, ['trigger_field1', 'trigger_field2'], priority) } ● store=True meaning: self._name (lambda s,c,u,ids,c: ids, None, 10)}→ ● Can be very expensive with wrong parameters or slow functions
  • 36. t @odony Common Problems: Slow Queries ● All SQL queries 500ms+ should be analyzed ● Use EXPLAIN ANALYZE to examine/measure you custom SQL queries and VIEWs ● Try to remove parts of the query until it's fast, then fix it ● Check cardinality of big JOINs ● Default domain evaluation strategy ● search([('picking_id.move_ids.partner_id', '!=', False)]) ● Implemented by combining “id IN (….)” parts ● Have a look at _auto_join in OpenERP 7.0 'move_ids': fields.one2many('stock.move', 'picking_id', string='Moves', _auto_join=True)
  • 37. t @odony Common Problems: Slow Queries ● No premature optimization: don't write SQL, use the ORM always during initial development ● If you detect a hot spot with load-tests, consider rewriting the inefficient parts in SQL ● But: ● Make sure you're not bypassing security mechanisms ● Don't create SQL injection vectors use query parameters,→ don't concatenate user input in your SQL strings.
  • 38. t @odony Common Problems: Lock Contention ● PostgreSQL guarantees transactional data integrity by taking heavy-weight locks → monitor_locks ● Updating a record blocks all FK locks on it until the transaction is completed! ● This will change with PostgreSQL 9.3 :-) ● This is independent from the transaction isolation level (Repeatable Read/Serializable/...) → Don't have long-running transactions! → Avoid updating “master data” resources in them! (user, company, stock location, product, …)
  • 39. t @odony Common Problems: Custom Locking ● Any kind of manual locking/queuing mechanism is dangerous, especially in Python ● Python locks can cause deadlocks that cannot be detected and broken by the system! ● Avoid it, and if you must, use the database as lock ● That's what scheduled jobs (ir.cron) do: ● SELECT FOR UPDATE on the cron job row ● → Automatic cleanup/release ● → Scales well and works in multi-process!
  • 40. t @odony Agenda ● Architecture / Deployment / Sizing ● Measuring & Analyzing ● Common Problems ● Anti-patterns
  • 41. t @odony Avoid Anti-Patterns: Master the framework! ● Make sure you really understand the browse() mechanisms! ● Make sure you properly use the batch API ● Don't write SQL unless you have to, e.g for: ● Analysis views ● Hot spot functions, name_search(), computed_fields(), ...
  • 42. t @odony Anti-Patterns: what's wrong? browse() must be used on lists to benefit from its optimizations!
  • 43. t @odony Anti-Patterns: what's wrong now? browse() use is OK now, but the related field is dangerous and costly, going through a possibly very large o2m just to find a single product ID
  • 44. t @odony Anti-Patterns: what's wrong here? The trigger on stock.move is for all fields which means it will trigger for each change, while we only care about tracking_id here