select bottleneck and insert into select doesn't work on cockroach db - bulkinsert

I have to union 2 tables like below query. and 'table2' has 15GB data. But it show errors. I set max-sql-memory=.80 and I don't know how to solve this.
When I execute this query with limit 50000 option, it works!
Even 'select * from table2' shows same error.
I think there are a select bottleneck somehow....
Also, with this query it is unusual only 1 of 3nodes's latency goes up. (AWS EC2 i3.xlarge type)
▶ Query
insert into table1 (
InvoiceID, PayerAccountId, LinkedAccountId, RecordType, RecordId, ProductName
)
select
InvoiceID, PayerAccountId, LinkedAccountId, RecordType, RecordId, ProductName
from table2;
▶ Error :
driver: bad connection
warning: connection lost!
opening new connection: all session settings will be lost
▶ Log :
W180919 04:59:20.452985 186 storage/raft_transport.go:465 [n3] raft transport stream to node 2 failed: rpc error: code = Unavailable desc = transport is closing
W180919 04:59:20.452996 190 vendor/google.golang.org/grpc/clientconn.go:1158 grpc: addrConn.createTransport failed to connect to {10.240.98.xxx:26257 0 }. Err :connection error: desc = "transport: Error while dialing cannot reuse client connection". Reconnecting...

If I'm understanding your question correctly, you're using a single statement to read ~15GB of data from table2 and insert it into table1. Unfortunately, as you've discovered this won't work. See limits for a single statement which covers exactly this scenario. Setting --max-sql-memory=.80 will not help and most likely will hurt as CockroachDB needs some breathing room as our memory tracking is not precise. The "bad connection warning" and the error you found in the logs are both symptoms which occur when a Cockroach process has crashed, presumably due to running out of memory.
If you need to copy the data from table2 to table1 transactionally then you're a bit out of luck at this time. While you could try using an explicit transaction and breaking the single INSERT statement into multiple statements, you'll very likely run into transaction size limits. If you can handle performing the copy non-transactionally then I'd suggest breaking the INSERT into pieces. Something along the lines of:
INSERT INTO table1 (...)
SELECT ... FROM table2 WHERE InvoiceID > $1 LIMIT 10000
RETURNING InvoiceID
The idea here is that you copy in 10k row batches. You would use the RETURNING InvoiceID clause to track the last InvoiceID that was copied and start the next insert from there.

Related

Insert statement from a linked server won't insert into the table. What am I missing here?

I'm using SQL Server 2016 to attempt to insert records from couple of tables located on a linked server. I can run the query and pull the data that I'm looking for, but when I attempted to insert it into the table it runs successfully, but no data is inserted into the SQL Server table. Here's my code;
insert into BTGroup (authorizedgroup, itemno)
select custno, prod
from OPENQUERY(NxtTest, '
select s.custno, p.prod, p.zauthorized
from pub.zics s
join pub.csp p on s.prod = p.prod
where p.zauthorized = 1
')
I feel like I'm missing something obvious here, but I'm new to working with linked servers so I'm a bit lost. Any help is greatly appreciated.
If you didn't get any error message and receive a message like (20 rows affected) in result window so everything is ok.
Check the selected database that contains BTGroup table when you are executing the query or change it to the full address. (e.g. MyDatabase.dbo.BTGroup)

select not working after putting where condition in nicknames?

I have a remote mainframe db2 database for which I have created nicknames in my db2 server .
Problem is as below -
When I run query
SELECT * FROM LNICKNAME.TABLE - It runs and I can get all columns.
but if I run below query it never gives me any output and keeps running .
SELECT * FROM LNICKNAME.TABLE a where a.columnB = 'ADH00040';
So technically it does not work if I add any where condition .
It doesn't seem like there is an error with your SELECT statement. So I am assuming that one of two things are happening:
Senario 1:
The file is really big and there isn't an index on columnB. If this is the case it would take long as the DB would have to read through each record and check if columnB = 'ADH00040'. To see how many records are in the table just run a count on the table
SELECT COUNT(*) FROM LNICKNAME.BMS_TABLE
Senario 2:
Something or someone is disconnecting your connection before your query is complete. I know you can limit the amount of CPU time a iSeries job is allowed before it gets ended forceably (CHGJOB CPUTIME(60000)). Is there no form of a job log that you could share with us?
Are you sure your value is into your table?
try a like :
SELECT * FROM LNICKNAME.TABLE a where a.columnB like '%ADH00040%';

SQL server error - string or binary data would be truncated - even though SELECT statement returns nothing

I have written a query in my stoted procedure, something like,
INSERT INTO Table1
(UniqueStr, Col1, Col2)
SELECT UniqueStr, Col1, Col2
FROM Table2
WHERE ...
It gives me error:
string or binary data would be truncated.
Here are the statistics.
Table1.UniqueStr is VARCHAR(11)
Table2.UniqueStr is VARCHAR(20)
Table2 has records having UniqueStr values of 11 characters and 15 characters.
The where clause of query is written in such a way that SELECT statement will never return records having UniqueStr length greater than 11.
The first weird scenario is - even though SELECT statement returns nothing (when run separately), it gives truncation error when run along with INSERT (i.e. INSERT...SELECT).
Second weird scenario is - it gives error only in Production environment. It gave no error in UAT environment. In Production environment, it ran fine for 1 day.
can anyone tell me what could be the issue?
Note: I fixed this error using SUBSTRING function but I could not find out the reason why SQL server gives this error?

SELECT FOR UPDATE with Subquery results in Deadlock

I have query when executed from different session is resulting in deadlock.
TAB1 (ID, TARGET, STATE, NEXT) AND ID is primary key
Column ID is the primary key.
SELECT *
FROM
TAB1 WHERE NEXT = (SELECT MIN(NEXT) FROM TAB1 WHERE TARGET=? AND STATE=?)
AND TARGET=? AND STATE=? FOR UPDATE
In the Oracle trace file, I see the statement:
DEADLOCK DETECTED
Current SQL statement for this session:
SELECT ID, TARGET, NEXT, STATE FROM TAB1
WHERE NEXT=(SELECT MIN(NEXT) FROM TAB1 WHERE (TARGET='$any') AND ( STATE = 0))
AND (TARGET='$any')
AND (STATE = 0) FOR UPDATE
The following deadlock is not an ORACLE error. It is a
deadlock due to user error in the design of an application
or from issuing incorrect ad-hoc SQL. The following
information may aid in determining the deadlock:
Deadlock graph:
---------Blocker(s)-------- ---------Waiter(s)---------
Resource Name process session holds waits process session holds waits
TX-00010012-0102905b 54 474 X 52 256 X
TX-000a0005-00a30961 52 256 X 54 474 X
session 474: DID 0001-0036-00000002 session 256: DID 0001-0034-00000002
session 256: DID 0001-0034-00000002 session 474: DID 0001-0036-00000002
Rows waited on:
Session 256: obj - rowid = 00013181 - AAATGBAAzAABtPTAAI
(dictionary objn - 78209, file - 51, block - 447443, slot - 8)
Session 474: obj - rowid = 00013181 - AAATGBAAzAABtPUAAJ
(dictionary objn - 78209, file - 51, block - 447444, slot - 9)
Information on the OTHER waiting sessions:
Session 256:
pid=52 serial=58842 audsid=43375302 user: 106/B2B_ISINTERNAL
O/S info: user: admwmt, term: spl099wmt04.compucom.local, ospid: , machine: spl099wmt04.compucom.local/10.16.0.41
program: JDBC Connect Client
Current SQL Statement:
SELECT ID, TARGET, NEXT, STATE FROM TAB1
WHERE NEXT=(SELECT MIN(NEXT) FROM TAB1 WHERE (TARGET='$any') AND ( STATE = 0))
AND (TARGET='$any')
AND (STATE = 0) FOR UPDATE
End of information on OTHER waiting sessions.
===================================================
Is there any way to avoid this? Rewriting the Query or Indexing?
I think the reason can be that you are actually selecting the same table twice with FOR UPDATE clause, once in the main query and once in subquery.
Update
Instead of trying to guess exactly how Oracle retrieves rows and force a plan, it may be easier to use one of the available UPDATE FOR locking features.
NOWAIT or SKIP LOCKED should be able to fix the problem. Although with NOWAIT you would probably need to add some application logic to retry after an error.
Since there are bind variables there may be multiple execution plans for the same SQL statement. This is normally a good thing, for example think about a query like this: select * from tab where status = ?. A full table scan would work best for a popular status, and an index scan would work better for a rare status. But if one plan uses an index and one uses a table, the same statement will retrieve resources in a different order, potentially causing a deadlock.
Forcing the statement to always use the same plan will prevent the deadlocks.
First, you will want to confirm my theory about multiple execution plans is correct. Look for multiple rows in this query, specifically look for different plan_hash_values for the same SQL_ID.
select child_number, plan_hash_value, gv$sql.*
from gv$sql
where sql_text like '%NEXT=(SELECT%';
Then it's a matter of forcing the statements to always use the same plan. One simple way is to find the outline that fixes a specific plan, and use the same set of hints for both statements. Hopefully the forced plan will still run well for all sets of bind variables.
select *
from table(dbms_xplan.display_cursor(
sql_id => '<SQL_ID from above>',
cursor_child_no => <child_number from above>,
format => '+outline')
);

Select Query on 2 tables, on different database servers

I am trying to generate a report by querying 2 databases (Sybase) in classic ASP.
I have created 2 connection strings:
connA for databaseA
connB for databaseB
Both databases are present on the same server (don't know if this matters)
Queries:
q1 = SELECT column1 INTO #temp FROM databaseA..table1 WHERE xyz="A"
q2 = SELECT columnA,columnB,...,columnZ FROM table2 a #temp b WHERE b.column1=a.columnB
followed by:
response.Write(rstsql) <br>
set rstSQL = CreateObject("ADODB.Recordset")<br>
rstSQL.Open q1, connA<br>
rstSQL.Open q2, connB
When I try to open up this page in a browser, I get error message:
Microsoft OLE DB Provider for ODBC Drivers error '80040e37'
[DataDirect][ODBC Sybase Wire Protocol driver][SQL Server]#temp not found. Specify owner.objectname or use sp_help to check whether the object exists (sp_help may produce lots of output).
Could anyone please help me understand what the problem is and help me fix it?
Thanks.
With both queries, it looks like you are trying to insert into #temp. #temp is located on one of the databases (for arguments sake, databaseA). So when you try to insert into #temp from databaseB, it reports that it does not exist.
Try changing it from Into #temp From to Into databaseA.dbo.#temp From in both statements.
Also, make sure that the connection strings have permissions on the other DB, otherwise this will not work.
Update: relating to the temp table going out of scope - if you have one connection string that has permissions on both databases, then you could use this for both queries (while keeping the connection alive). While querying the table in the other DB, be sure to use [DBName].[Owner].[TableName] format when referring to the table.
your temp table is out of scope, it is only 'alive' during the first connection and will not be available in the 2nd connection
Just move all of it in one block of code and execute it inside one conection
temp is out of scope in q2.
All your work can be done in one query:
SELECT a.columnA, a.columnB,..., a.columnZ
FROM table2 a
INNER JOIN (SELECT databaseA..table1.column1
FROM databaseA..table1
WHERE databaseA..table1.xyz = 'A') b
ON a.columnB = b.column1