Is there any way to limit the size of flow table in Open vSwitch and to verify that it is working? - overflow

I have used the following instruction to restrict the flow table 0 to 5 entries only:
$ sudo ovs-vsctl -- --id=#ft create Flow_Table flow_limit=5 overflow_policy=refuse -- set Bridge s1 flow_tables=0=#ft
When i dump flows, it applies the limit 5 to flow table 0 as follows:
sudo ovs-ofctl dump-tables s1
OFPST_TABLE reply (xid=0x2):
table 0 ("classifier"):
active=1, lookup=26, matched=0
max_entries=5
But when i ping from h1 to h2, it keep storing the ping more than 5 as follows

A flow entry is defined as a unique tuple.
There is only one entry, h1 to h2. Although there are multiple pings, the same flow entry is receiving packets, which is why it says, "active=1".
If you were to pingall, the response would read, "active=2":
h1 to h2
h2 to h1

Related

Sync ALTER TABLE ... DELETE on all replicas of a Clickhouse cluster

TL;DR
There are 2 questions:
How to correctly do a synchronous ALTER TABLE .. DELETE on a Clickhouse cluster.
Will data be deleted from all replicas when using ALTER TABLE .. DELETE with mutations_sync = 2 settings and without using ON CLUSTER. Or how could this be verified
Long
There are 2 CH installations: single-server (H1) and cluster (3 nodes, H2). I have created a table foo with the engines: H1 - ReplacingMergeTree, H2 - ReplicatedReplacingMergeTree (using ON CLUSTER bar). Then I make requests:
For each request, I generated 1kk rows (about 200 MB was obtained approximately).
Request to H1 (single-server)
clickhouse-client -h $H1 --queries-file=queries.sql
queries.sql:
ALTER TABLE foo DELETE WHERE 1 SETTINGS mutations_sync = 0;
SELECT * FROM foo LIMIT 1
The result of SELECT shows some record, that hasn't been deleted yet. Stand to reason.
Do the same, but with mutations_sync = 1. The SELECT returned 0 rows. Same with mutations_sync = 2. So far, everything is as expected.
Request to H2 (cluster):
clickhouse-client -h $H2 --queries-file=queries.sql
queries.sql:
ALTER TABLE foo ON CLUSTER bar DELETE WHERE 1 SETTINGS mutations_sync = 2;
SELECT * FROM foo LIMIT 1
The SELECT returns some record, although it seems it shouldn't, since mutations_sync = 2 means that the request must complete on all replicas before it is finished (or am I misunderstanding something?)
Do the same, but remove ON CLUSTER bar from ALTER TABLE. In this case, the result of SELECT is 0 rows.
I assume that the reason of such behavior in case 3 is due to when the ON CLUSTER option is used, the request goes to ZooKeeper, and immediately complete because ZK just gets the request to send it to all replicas, but don't wait for its completion. Is that right?
I want to check if data is deleted from all replicas in case 4. I've tried making requests like:
#!/bin/bash
clickhouse-client -h $H2_REPLIC1 --query="ALTER TABLE topics ON CLUSTER dc2_test DELETE WHERE 1 SETTINGS mutations_sync = 0";
clickhouse-client -h $H2_REPLIC2 --query="SELECT * FROM topics LIMIT 1 FORMAT TabSeparated";
But both using mutations_sync = 0 and mutations_sync = 2, the SELECT returns 0 rows (even if increase number of generated rows in foo to 30kk). I don't understand this behavior, so I can't get the answer to my 2nd question (in TL;DR)
No way.
No.
Mutations were implemented as an ADMIN operations to solve GDPR problem, but not daily basis business (USER) tasks.
That's why mutations don't not provide consistency / atomicity.
And that's why mutations are very unreliable if you are trying to use them to solve business logic tasks (USER tasks).

How to change the read/write ratio of sysbench oltp_read_write script

I'm using the sysbench(1.1.0) to test the performance of MySQL, and I want to test the scene that read:write is 95%:5%. Are there any parameters to change the read/write ratio?
You can have a look at the oltp_read_write script:
function event()
if not sysbench.opt.skip_trx then
begin()
end
execute_point_selects()
if sysbench.opt.range_selects then
execute_simple_ranges()
execute_sum_ranges()
execute_order_ranges()
execute_distinct_ranges()
end
execute_index_updates()
execute_non_index_updates()
execute_delete_inserts()
if not sysbench.opt.skip_trx then
commit()
end
check_reconnect()
end
This script define the query in a transaction, and the options are below(sysbench oltp_read_write.lua help):
oltp_read_write.lua options:
--auto_inc[=on|off] Use AUTO_INCREMENT column as Primary Key (for MySQL), or its alternatives in other DBMS. When disabled, use client-generated IDs [on]
--create_secondary[=on|off] Create a secondary index in addition to the PRIMARY KEY [on]
--create_table_options=STRING Extra CREATE TABLE options []
--delete_inserts=N Number of DELETE/INSERT combinations per transaction [1]
--distinct_ranges=N Number of SELECT DISTINCT queries per transaction [1]
--index_updates=N Number of UPDATE index queries per transaction [1]
--mysql_storage_engine=STRING Storage engine, if MySQL is used [innodb]
--non_index_updates=N Number of UPDATE non-index queries per transaction [1]
--order_ranges=N Number of SELECT ORDER BY queries per transaction [1]
--pgsql_variant=STRING Use this PostgreSQL variant when running with the PostgreSQL driver. The only currently supported variant is 'redshift'. When enabled, create_secondary is automatically disabled, and delete_inserts is set to 0
--point_selects=N Number of point SELECT queries per transaction [10]
--range_selects[=on|off] Enable/disable all range SELECT queries [on]
--range_size=N Range size for range SELECT queries [100]
--reconnect=N Reconnect after every N events. The default (0) is to not reconnect [0]
--secondary[=on|off] Use a secondary index in place of the PRIMARY KEY [off]
--simple_ranges=N Number of simple range SELECT queries per transaction [1]
--skip_trx[=on|off] Don't start explicit transactions and execute all queries in the AUTOCOMMIT mode [off]
--sum_ranges=N Number of SELECT SUM() queries per transaction [1]
--table_size=N Number of rows per table [10000]
--tables=N Number of tables [1]
So, the default read/write ratio is 10+4/1+1+2+2, and you can change the read/write ratio just by changing the option number. For example:
sysbench oltp_read_write.lua --range_selects=off --point_selects=100 xxx
Then the read/write ratio is 100+4/1+1+2+2.

Concurrent get timestamp plus sequence from Oracle

background: two application nodes, three Oracle node.
I have a sequence, ddl like this:
CREATE SEQUENCE "XXX_SEQ" MINVALUE 10 MAXVALUE 99 INCREMENT BY 1 START WITH 10 NOCACHE ORDER CYCLE ;
And I use this to generate the id as my primary key
SELECT 'FWK2-' || TO_CHAR(SYS_EXTRACT_UTC(CURRENT_TIMESTAMP), 'YYYYMMDDHH24MISSFF2') || '-' || XXX_SEQ.nextval AS MSG_REQ_ID FROM DUAL;
But when concurrent generate the id, it hit the duplicate issue, in milliseconds it generate the duplicate id.
It is part of the log
2019-09-03 04:40:17,501 FWK2-2019090304401699-43
2019-09-03 04:40:17,010 FWK2-2019090304401699-43
And I checked in the 99 milliseconds, there are no more than 99 msg that would make the sequence cycle to hit the duplicate issue.
I suspect it should be the ddl issue
Dose anyone know about how to optimize it?
actually, in my PROD env, i have 3 application that use this method to generate, and each application has 2 nodes. Suppose 3 application are A,B,C.
A and C has only one place to generate id
B has more than three place to generate id
and one more strange that as my sequence is order, why the id in db is not order?
FWK2-2019090304394159-34
FWK2-2019090304394280-37
FWK2-2019090304394298-35
FWK2-2019090304394311-36
FWK2-2019090304394354-40
FWK2-2019090304394359-38
Update
Although I test with sequence NOCACHE, ORDER, under Jmeter use 3 api, each api 300 threads.
The id would not be order, like this:
FWK2-2019090403025046-67
FWK2-2019090403025046-68
FWK2-2019090403025050-69
FWK2-2019090403025053-10
FWK2-2019090403025053-11
FWK2-2019090403025053-31
FWK2-2019090403025053-39
FWK2-2019090403025053-40
FWK2-2019090403025053-41
FWK2-2019090403025053-42
FWK2-2019090403025053-46
FWK2-2019090403025053-47
FWK2-2019090403025053-70
FWK2-2019090403025053-71
FWK2-2019090403025053-72

Oracle 10 MERGE performance

I had a very strange performance related problem with MERGE in Oracle 10. In a few words, I have a stored procedure that calculates and stores user rank based on her activity in the system and contains just one MERGE statement:
MERGE INTO user_ranks target USING
([complex query that returns rank_id and user_id])src ON
(src.user_id = target.user_id)
WHEN MATCHED THEN UPDATE SET target.rank_id = src.rank_id
WHEN NOT MATCHED THEN INSERT (target.user_id, target.rank_id)
VALUES (src.user_id, src.rank_id);
// user_ranks table structure:
CREATE TABLE user_ranks (user_id INT NOT NULL
PRIMARY KEY USING INDEX (CREATE UNIQUE INDEX UQ_uid_uranks ON user_ranks(user_id)),
rank_id INT NOT NULL,
CONSTRAINT FK_uid_uranks FOREIGN KEY (user_id) REFERENCES users(id),
CONSTRAINT FK_rid_uranks FOREIGN KEY(rank_id) REFERENCES ranks(id));
// no index on rank_id - intentionally, ranks table is a lookup with
// a very few records and no delete/update allowed
The subquery which is used as a source for MERGE returns at most 1 record (user_id is passed as parameter to the procedure). It's quite expensive but execution time is acceptable (1-1.2 sec). The problem is that MERGE execution time hikes to more than 40 seconds, and I have no clue why. I tried using LEADING hint with no success. But if I split the statement into 2 parts, first one - run SELECT subquery and store result(rank_id) into variable and then merge - MERGE ... USING (SELECT user_id, rank_id FROM DUAL)src ... everything works just fine. From what I read, there are known issues with Oracle's MERGE, but they are mostly related to triggers (no triggers in my case). It also says that MERGE works slower than combination of INSERT and UPDATE, but I believe the "normal" difference is around 5-10%, not 30 times...
I'm trying to understand what I did wrong... Thanks for your suggestions.
Update
Execution plan is quite long to post it here, in short : subquery cost by itself is 12737, with merge - 76305. Stats output for merge :
> Statistics
108 recursive calls
4 db block gets
45630447 consistent gets
24905 physical reads
0 redo size
620 bytes sent via SQL*Net to client
1183 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
2 sorts (memory)
0 sorts (disk)
subquery alone :
> Statistics
8 recursive calls
0 db block gets
34 consistent gets
0 physical reads
0 redo size
558 bytes sent via SQL*Net to client
234 bytes received via SQL*Net from client
1 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
If you've set up SQL*Plus autotrace it would be a matter of seconds to see which part of the actual execution plan has caused the most physical and logical I/O and used the most memory.
Note that the information you get using this method is much more precise than a simple explain plan.

Oracle 10g small Blob or Clob not being stored inline?

According to the documents I've read, the default storage for a CLOB or BLOB is inline, which means that if it is less than approx 4k in size then it will be held in the table.
But when I test this on a dummy table in Oracle (10.2.0.1.0) the performance and response from Oracle Monitor (by Allround Automations) suggest that it is being held outwith the table.
Here's my test scenario ...
create table clobtest ( x int primary key, y clob, z varchar(100) )
;
insert into clobtest
select object_id, object_name, object_name
from all_objects where rownum < 10001
;
select COLUMN_NAME, IN_ROW
from user_lobs
where table_name = 'CLOBTEST'
;
This shows: Y YES (suggesting that Oracle will store the clob in the row)
select x, y from CLOBTEST where ROWNUM < 1001 -- 8.49 seconds
select x, z from CLOBTEST where ROWNUM < 1001 -- 0.298 seconds
So in this case, the CLOB values will have a maximum length of 30 characters, so should always be inline. If I run Oracle Monitor, it shows a LOB.Length followed by a LOB.Read() for each row returned, again suggesting that the clob values are held outwith the table.
I also tried creating the table like this
create table clobtest
( x int primary key, y clob, z varchar(100) )
LOB (y) STORE AS (ENABLE STORAGE IN ROW)
but got exactly the same results.
Does anyone have any suggestions how I can force (persuade, encourage) Oracle to store the clob value in-line in the table? (I'm hoping to achieve similar response times to reading the varchar2 column z)
UPDATE: If I run this SQL
select COLUMN_NAME, IN_ROW, l.SEGMENT_NAME, SEGMENT_TYPE, BYTES, BLOCKS, EXTENTS
from user_lobs l
JOIN USER_SEGMENTS s
on (l.Segment_Name = s. segment_name )
where table_name = 'CLOBTEST'
then I get the following results ...
Y YES SYS_LOB0000398621C00002$$ LOBSEGMENT 65536 8 1
The behavior of Oracle LOBs is the following.
A LOB is stored inline when:
(
The size is lower or equal than 3964
AND
ENABLE STORAGE IN ROW has been defined in the LOB storage clause
) OR (
The value is NULL
)
A LOB is stored out-of-row when:
(
The value is not NULL
) AND (
Its size is higher than 3964
OR
DISABLE STORAGE IN ROW has been defined in the LOB storage clause
)
Now this is not the only issue which may impact performance.
If the LOBs are finally not stored inline, the default behavior of Oracle is to avoid caching them (only inline LOBs are cached in the buffer cache with the other fields of the row). To tell Oracle to also cache non inlined LOBs, the CACHE option should be used when the LOB is defined.
The default behavior is ENABLE STORAGE IN ROW, and NOCACHE, which means small LOBs will be inlined, large LOBs will not (and will not be cached).
Finally, there is also a performance issue at the communication protocol level. Typical Oracle clients will perform 2 additional roundtrips per LOBs to fetch them:
- one to retrieve the size of the LOB and allocate memory accordingly
- one to fetch the data itself (provided the LOB is small)
These extra roundtrips are performed even if an array interface is used to retrieve the results. If you retrieve 1000 rows and your array size is large enough, you will pay for 1 roundtrip to retrieve the rows, and 2000 roundtrips to retrieve the content of the LOBs.
Please note it does not depend on the fact the LOB is stored inline or not. They are complete different problems.
To optimize at the protocol level, Oracle has provided a new OCI verb to fetch several LOBs in one roundtrips (OCILobArrayRead). I don't know if something similar exists with JDBC.
Another option is to bind the LOB on client side as if it was a big RAW/VARCHAR2. This only works if a maximum size of the LOB can be defined (since the maximum size must be provided at bind time). This trick avoids the extra rountrips: the LOBs are just processed like RAW or VARCHAR2. We use it a lot in our LOB intensive applications.
Once the number of roundtrips have been optimized, the packet size (SDU) can be resized in the net configuration to better fit the situation (i.e. a limited number of large roundtrips). It tends to reduce the "SQL*Net more data to client" and "SQL*Net more data from client" wait events.
If you're "hoping to achieve similar response times to reading the varchar2 column z", then you'll be disappointed in most cases.
If you're using a CLOB I suppose you need to store more than 4,000 bytes, right? Then if you need to read more bytes that's going to take longer.
BUT if you have a case where yes, you use a CLOB, but you're interested (in some instances) only in the first 4,000 bytes of the column (or less), then you have a chance of getting similar performance.
It looks like Oracle can optimize the retrieval if you use something like DBMS_LOB.SUBSTR and ENABLE STORAGE IN ROW CACHE clause with your table. Example:
CREATE TABLE clobtest (x INT PRIMARY KEY, y CLOB)
LOB (y) STORE AS (ENABLE STORAGE IN ROW CACHE);
INSERT INTO clobtest VALUES (0, RPAD('a', 4000, 'a'));
UPDATE clobtest SET y = y || y || y;
INSERT INTO clobtest SELECT rownum, y FROM all_objects, clobtest WHERE rownum < 1000;
CREATE TABLE clobtest2 (x INT PRIMARY KEY, z VARCHAR2(4000));
INSERT INTO clobtest2 VALUES (0, RPAD('a', 4000, 'a'));
INSERT INTO clobtest2 SELECT rownum, z FROM all_objects, clobtest2 WHERE rownum < 1000;
COMMIT;
In my tests on 10.2.0.4 and 8K block, these two queries give very similar performance:
SELECT x, DBMS_LOB.SUBSTR(y, 4000) FROM clobtest;
SELECT x, z FROM clobtest2;
Sample from SQL*Plus (I ran the queries multiple times to remove physical IO's):
SQL> SET AUTOTRACE TRACEONLY STATISTICS
SQL> SET TIMING ON
SQL>
SQL> SELECT x, y FROM clobtest;
1000 rows selected.
Elapsed: 00:00:02.96
Statistics
------------------------------------------------------
0 recursive calls
0 db block gets
3008 consistent gets
0 physical reads
0 redo size
559241 bytes sent via SQL*Net to client
180350 bytes received via SQL*Net from client
2002 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1000 rows processed
SQL> SELECT x, DBMS_LOB.SUBSTR(y, 4000) FROM clobtest;
1000 rows selected.
Elapsed: 00:00:00.32
Statistics
------------------------------------------------------
0 recursive calls
0 db block gets
2082 consistent gets
0 physical reads
0 redo size
18993 bytes sent via SQL*Net to client
1076 bytes received via SQL*Net from client
68 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1000 rows processed
SQL> SELECT x, z FROM clobtest2;
1000 rows selected.
Elapsed: 00:00:00.18
Statistics
------------------------------------------------------
0 recursive calls
0 db block gets
1005 consistent gets
0 physical reads
0 redo size
18971 bytes sent via SQL*Net to client
1076 bytes received via SQL*Net from client
68 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1000 rows processed
As you can see, consistent gets are quite higher, but SQL*Net roundtrips and bytes are nearly identical in the last two queries, and that apparently makes a big difference in execution time!
One warning though: the difference in consistent gets might become a more likely performance issue if you have large result sets, as you won't be able to keep everything in buffer cache and you'll end up with very expensive physical reads...
Good luck!
Cheers
Indeed, it is stored within the row. You are likely dealing with the simple overhead of using a LOB instead of a varchar. Nothing is free. The DB probably doesn't know ahead of time where to find the row, so it probably still "follows a pointer" and does extra work just in case the LOB is big. If you can get by with a varchar, you should. Even old hacks like 2 varchars to deal with 8000 characters might solve your business case with higher performance.
LOBS are slow, difficult to query, etc. On the positive, they can be 4G.
What would be interesting to try is to shove something just over 4000 bytes into that clob, and see what the performance looks like. Maybe it is about the same speed? This would tell you that it's overhead slowing you down.
Warning, at some point network traffic to your PC slows you down on these kind of tests.
Minimize this by wrapping in a count, this isolates the work to the server:
select count(*) from (select x,y from clobtest where rownum<1001)
You can achieve similar effects with "set autot trace", but there will be tracing overhead too.
There are two indirections when it comes to CLOBs and BLOBs:
The LOB value might be stored in a different database segment than the rest of the row.
When you query the row, only the non-LOB fields are contained in the result set and accessing the LOB-fields requries one or more additional round trips between the client and the server (per row!).
I don't quite know how you measure the execution time and I've never used Oracle Monitor, but you might primarily be affected by the second indirection. Depending on the client software you use, it is possible to reduce the round trips. E.g. when you use ODP.NET, the parameter is called InitialLobFetchSize.
Update:
One one to tell which of the two indirections is relevant, you can run your LOB query with 1000 rows twice. If the time drops significantly from the first to the second run, it's indirection 1. On the second run, the caching pays off and access to the separate database segment isn't very relevant anymore. If the time stays about the same, it's the second indirection, namely the round trips between the client and the server, which cannot improve between two runs.
The time of more than 8 seconds for 1000 rows in a very simple query indicate it's indirection 2 because 8 seconds for 1000 rows can't really be explained with disk access unless your data is very scattered and your disk system under heavy load.
This is the key information (how to read LOB without extra roundtrips), which is not available in Oracle's documentation I think:
Another option is to bind the LOB on client side as if it was a big
RAW/VARCHAR2. This only works if a maximum size of the LOB can be
defined (since the maximum size must be provided at bind time). This
trick avoids the extra rountrips: the LOBs are just processed like RAW
or VARCHAR2. We use it a lot in our LOB intensive applications.
I had problem with loading simple table (few GB) with one blob column ( 14KB => thousands of rows) and I was investigating it for a long time, tried a lot of lob storage tunings (DB_BLOCK_SIZE for new tablespace, lob storage specification - CHUNK ), sqlnet.ora settings, client prefetching attributes, but this (treat BLOB as LONG RAW with OCCI ResultSet->setBufferData on client side) was the most important thing (persuade oracle to send blob column immediately without sending lob locator at first and loading each lob separately based on lob locator.
Now I can get even ~ 500Mb/s throughput (with columns < 3964B).
Our 14KB blob will be separated into multiple columns - so it'll be stored in row to get almost sequential reads from HDD. With one 14KB blob (one column) I get ~150Mbit/s because of non-sequential reads (iostat: low amount of merged read requests).
NOTE: don't forget to set also lob prefetch size/length:
err = OCIAttrSet(session, (ub4) OCI_HTYPE_SESSION, (void *) &default_lobprefetch_size, 0, (ub4) OCI_ATTR_DEFAULT_LOBPREFETCH_SIZE, errhp);
But I don't know how is it possible to achieve the same fetching throughput with ODBC connector. I was trying it without any success.

Resources