SlideShare una empresa de Scribd logo
1 de 44
Descargar para leer sin conexión
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

Más contenido relacionado

La actualidad más candente

Why and how to develop OpenERP test scenarios (in python and using OERPScenar...
Why and how to develop OpenERP test scenarios (in python and using OERPScenar...Why and how to develop OpenERP test scenarios (in python and using OERPScenar...
Why and how to develop OpenERP test scenarios (in python and using OERPScenar...Odoo
 
Simple Odoo ERP auto scaling on AWS
Simple Odoo ERP auto scaling on AWSSimple Odoo ERP auto scaling on AWS
Simple Odoo ERP auto scaling on AWSJulien Lecadou,MSc.
 
New Framework - ORM
New Framework - ORMNew Framework - ORM
New Framework - ORMOdoo
 
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
 
Load Testing - How to Stress Your Odoo with Locust
Load Testing - How to Stress Your Odoo with LocustLoad Testing - How to Stress Your Odoo with Locust
Load Testing - How to Stress Your Odoo with LocustOdoo
 
Odoo - Create themes for website
Odoo - Create themes for websiteOdoo - Create themes for website
Odoo - Create themes for websiteOdoo
 
Odoo's Test Framework - Learn Best Practices
Odoo's Test Framework - Learn Best PracticesOdoo's Test Framework - Learn Best Practices
Odoo's Test Framework - Learn Best PracticesOdoo
 
OpenERP Performance Benchmark
OpenERP Performance BenchmarkOpenERP Performance Benchmark
OpenERP Performance BenchmarkAudaxis
 
Building l10n Payroll Structures from the Ground up
Building l10n Payroll Structures from the Ground upBuilding l10n Payroll Structures from the Ground up
Building l10n Payroll Structures from the Ground upOdoo
 
Security: Odoo Code Hardening
Security: Odoo Code HardeningSecurity: Odoo Code Hardening
Security: Odoo Code HardeningOdoo
 
Budget Control with mis_builder 3 (2017)
Budget Control with mis_builder 3 (2017)Budget Control with mis_builder 3 (2017)
Budget Control with mis_builder 3 (2017)acsone
 
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
 
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
 
Odoo External API
Odoo External APIOdoo External API
Odoo External APIOdoo
 
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
 
Postgresql database administration volume 1
Postgresql database administration volume 1Postgresql database administration volume 1
Postgresql database administration volume 1Federico Campoli
 
Infrastructure & System Monitoring using Prometheus
Infrastructure & System Monitoring using PrometheusInfrastructure & System Monitoring using Prometheus
Infrastructure & System Monitoring using PrometheusMarco Pas
 

La actualidad más candente (20)

Why and how to develop OpenERP test scenarios (in python and using OERPScenar...
Why and how to develop OpenERP test scenarios (in python and using OERPScenar...Why and how to develop OpenERP test scenarios (in python and using OERPScenar...
Why and how to develop OpenERP test scenarios (in python and using OERPScenar...
 
Simple Odoo ERP auto scaling on AWS
Simple Odoo ERP auto scaling on AWSSimple Odoo ERP auto scaling on AWS
Simple Odoo ERP auto scaling on AWS
 
New Framework - ORM
New Framework - ORMNew Framework - ORM
New Framework - ORM
 
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
 
Load Testing - How to Stress Your Odoo with Locust
Load Testing - How to Stress Your Odoo with LocustLoad Testing - How to Stress Your Odoo with Locust
Load Testing - How to Stress Your Odoo with Locust
 
Odoo - Create themes for website
Odoo - Create themes for websiteOdoo - Create themes for website
Odoo - Create themes for website
 
Odoo's Test Framework - Learn Best Practices
Odoo's Test Framework - Learn Best PracticesOdoo's Test Framework - Learn Best Practices
Odoo's Test Framework - Learn Best Practices
 
OpenERP Performance Benchmark
OpenERP Performance BenchmarkOpenERP Performance Benchmark
OpenERP Performance Benchmark
 
Building l10n Payroll Structures from the Ground up
Building l10n Payroll Structures from the Ground upBuilding l10n Payroll Structures from the Ground up
Building l10n Payroll Structures from the Ground up
 
Security: Odoo Code Hardening
Security: Odoo Code HardeningSecurity: Odoo Code Hardening
Security: Odoo Code Hardening
 
Prometheus and Grafana
Prometheus and GrafanaPrometheus and Grafana
Prometheus and Grafana
 
Budget Control with mis_builder 3 (2017)
Budget Control with mis_builder 3 (2017)Budget Control with mis_builder 3 (2017)
Budget Control with mis_builder 3 (2017)
 
Odoo ERP functional
Odoo ERP functionalOdoo ERP functional
Odoo ERP functional
 
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
 
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
 
Odoo External API
Odoo External APIOdoo External API
Odoo External API
 
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
 
Postgresql database administration volume 1
Postgresql database administration volume 1Postgresql database administration volume 1
Postgresql database administration volume 1
 
Introduction to Slurm
Introduction to SlurmIntroduction to Slurm
Introduction to Slurm
 
Infrastructure & System Monitoring using Prometheus
Infrastructure & System Monitoring using PrometheusInfrastructure & System Monitoring using Prometheus
Infrastructure & System Monitoring using Prometheus
 

Similar a 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 a 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
 

Más de 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
 
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
 
Digital Transformation at Old MacDonald Farms: A Personal Story
Digital Transformation at Old MacDonald Farms: A Personal StoryDigital Transformation at Old MacDonald Farms: A Personal Story
Digital Transformation at Old MacDonald Farms: A Personal StoryOdoo
 

Más de 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!
 
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
 
Digital Transformation at Old MacDonald Farms: A Personal Story
Digital Transformation at Old MacDonald Farms: A Personal StoryDigital Transformation at Old MacDonald Farms: A Personal Story
Digital Transformation at Old MacDonald Farms: A Personal Story
 

Último

Mondelez State of Snacking and Future Trends 2023
Mondelez State of Snacking and Future Trends 2023Mondelez State of Snacking and Future Trends 2023
Mondelez State of Snacking and Future Trends 2023Neil Kimberley
 
Regression analysis: Simple Linear Regression Multiple Linear Regression
Regression analysis:  Simple Linear Regression Multiple Linear RegressionRegression analysis:  Simple Linear Regression Multiple Linear Regression
Regression analysis: Simple Linear Regression Multiple Linear RegressionRavindra Nath Shukla
 
Monthly Social Media Update April 2024 pptx.pptx
Monthly Social Media Update April 2024 pptx.pptxMonthly Social Media Update April 2024 pptx.pptx
Monthly Social Media Update April 2024 pptx.pptxAndy Lambert
 
Best Basmati Rice Manufacturers in India
Best Basmati Rice Manufacturers in IndiaBest Basmati Rice Manufacturers in India
Best Basmati Rice Manufacturers in IndiaShree Krishna Exports
 
Creating Low-Code Loan Applications using the Trisotech Mortgage Feature Set
Creating Low-Code Loan Applications using the Trisotech Mortgage Feature SetCreating Low-Code Loan Applications using the Trisotech Mortgage Feature Set
Creating Low-Code Loan Applications using the Trisotech Mortgage Feature SetDenis Gagné
 
Monte Carlo simulation : Simulation using MCSM
Monte Carlo simulation : Simulation using MCSMMonte Carlo simulation : Simulation using MCSM
Monte Carlo simulation : Simulation using MCSMRavindra Nath Shukla
 
Unlocking the Secrets of Affiliate Marketing.pdf
Unlocking the Secrets of Affiliate Marketing.pdfUnlocking the Secrets of Affiliate Marketing.pdf
Unlocking the Secrets of Affiliate Marketing.pdfOnline Income Engine
 
Event mailer assignment progress report .pdf
Event mailer assignment progress report .pdfEvent mailer assignment progress report .pdf
Event mailer assignment progress report .pdftbatkhuu1
 
9599632723 Top Call Girls in Delhi at your Door Step Available 24x7 Delhi
9599632723 Top Call Girls in Delhi at your Door Step Available 24x7 Delhi9599632723 Top Call Girls in Delhi at your Door Step Available 24x7 Delhi
9599632723 Top Call Girls in Delhi at your Door Step Available 24x7 DelhiCall Girls in Delhi
 
Cracking the Cultural Competence Code.pptx
Cracking the Cultural Competence Code.pptxCracking the Cultural Competence Code.pptx
Cracking the Cultural Competence Code.pptxWorkforce Group
 
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
 
Call Girls In Holiday Inn Express Gurugram➥99902@11544 ( Best price)100% Genu...
Call Girls In Holiday Inn Express Gurugram➥99902@11544 ( Best price)100% Genu...Call Girls In Holiday Inn Express Gurugram➥99902@11544 ( Best price)100% Genu...
Call Girls In Holiday Inn Express Gurugram➥99902@11544 ( Best price)100% Genu...lizamodels9
 
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
 
HONOR Veterans Event Keynote by Michael Hawkins
HONOR Veterans Event Keynote by Michael HawkinsHONOR Veterans Event Keynote by Michael Hawkins
HONOR Veterans Event Keynote by Michael HawkinsMichael W. Hawkins
 
Grateful 7 speech thanking everyone that has helped.pdf
Grateful 7 speech thanking everyone that has helped.pdfGrateful 7 speech thanking everyone that has helped.pdf
Grateful 7 speech thanking everyone that has helped.pdfPaul Menig
 
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
 
VIP Call Girls Gandi Maisamma ( Hyderabad ) Phone 8250192130 | ₹5k To 25k Wit...
VIP Call Girls Gandi Maisamma ( Hyderabad ) Phone 8250192130 | ₹5k To 25k Wit...VIP Call Girls Gandi Maisamma ( Hyderabad ) Phone 8250192130 | ₹5k To 25k Wit...
VIP Call Girls Gandi Maisamma ( Hyderabad ) Phone 8250192130 | ₹5k To 25k Wit...Suhani Kapoor
 
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
 

Último (20)

Mondelez State of Snacking and Future Trends 2023
Mondelez State of Snacking and Future Trends 2023Mondelez State of Snacking and Future Trends 2023
Mondelez State of Snacking and Future Trends 2023
 
Regression analysis: Simple Linear Regression Multiple Linear Regression
Regression analysis:  Simple Linear Regression Multiple Linear RegressionRegression analysis:  Simple Linear Regression Multiple Linear Regression
Regression analysis: Simple Linear Regression Multiple Linear Regression
 
Monthly Social Media Update April 2024 pptx.pptx
Monthly Social Media Update April 2024 pptx.pptxMonthly Social Media Update April 2024 pptx.pptx
Monthly Social Media Update April 2024 pptx.pptx
 
Best Basmati Rice Manufacturers in India
Best Basmati Rice Manufacturers in IndiaBest Basmati Rice Manufacturers in India
Best Basmati Rice Manufacturers in India
 
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
 
Creating Low-Code Loan Applications using the Trisotech Mortgage Feature Set
Creating Low-Code Loan Applications using the Trisotech Mortgage Feature SetCreating Low-Code Loan Applications using the Trisotech Mortgage Feature Set
Creating Low-Code Loan Applications using the Trisotech Mortgage Feature Set
 
Monte Carlo simulation : Simulation using MCSM
Monte Carlo simulation : Simulation using MCSMMonte Carlo simulation : Simulation using MCSM
Monte Carlo simulation : Simulation using MCSM
 
Unlocking the Secrets of Affiliate Marketing.pdf
Unlocking the Secrets of Affiliate Marketing.pdfUnlocking the Secrets of Affiliate Marketing.pdf
Unlocking the Secrets of Affiliate Marketing.pdf
 
Event mailer assignment progress report .pdf
Event mailer assignment progress report .pdfEvent mailer assignment progress report .pdf
Event mailer assignment progress report .pdf
 
9599632723 Top Call Girls in Delhi at your Door Step Available 24x7 Delhi
9599632723 Top Call Girls in Delhi at your Door Step Available 24x7 Delhi9599632723 Top Call Girls in Delhi at your Door Step Available 24x7 Delhi
9599632723 Top Call Girls in Delhi at your Door Step Available 24x7 Delhi
 
Cracking the Cultural Competence Code.pptx
Cracking the Cultural Competence Code.pptxCracking the Cultural Competence Code.pptx
Cracking the Cultural Competence Code.pptx
 
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
 
Call Girls In Holiday Inn Express Gurugram➥99902@11544 ( Best price)100% Genu...
Call Girls In Holiday Inn Express Gurugram➥99902@11544 ( Best price)100% Genu...Call Girls In Holiday Inn Express Gurugram➥99902@11544 ( Best price)100% Genu...
Call Girls In Holiday Inn Express Gurugram➥99902@11544 ( Best price)100% Genu...
 
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
 
HONOR Veterans Event Keynote by Michael Hawkins
HONOR Veterans Event Keynote by Michael HawkinsHONOR Veterans Event Keynote by Michael Hawkins
HONOR Veterans Event Keynote by Michael Hawkins
 
Grateful 7 speech thanking everyone that has helped.pdf
Grateful 7 speech thanking everyone that has helped.pdfGrateful 7 speech thanking everyone that has helped.pdf
Grateful 7 speech thanking everyone that has helped.pdf
 
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
 
VIP Call Girls Gandi Maisamma ( Hyderabad ) Phone 8250192130 | ₹5k To 25k Wit...
VIP Call Girls Gandi Maisamma ( Hyderabad ) Phone 8250192130 | ₹5k To 25k Wit...VIP Call Girls Gandi Maisamma ( Hyderabad ) Phone 8250192130 | ₹5k To 25k Wit...
VIP Call Girls Gandi Maisamma ( Hyderabad ) Phone 8250192130 | ₹5k To 25k Wit...
 
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
 
Forklift Operations: Safety through Cartoons
Forklift Operations: Safety through CartoonsForklift Operations: Safety through Cartoons
Forklift Operations: Safety through Cartoons
 

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